forked from OSchip/llvm-project
LiveIntervalAnalysis: Fix handleMove() re-using the wrong value number
This fixes http://llvm.org/PR27856 llvm-svn: 270619
This commit is contained in:
parent
94ddce2c0e
commit
fc4c8a1e46
|
@ -1257,20 +1257,16 @@ private:
|
||||||
// value.
|
// value.
|
||||||
LiveRange::iterator NewSegment = NewIdxIn;
|
LiveRange::iterator NewSegment = NewIdxIn;
|
||||||
LiveRange::iterator Next = std::next(NewSegment);
|
LiveRange::iterator Next = std::next(NewSegment);
|
||||||
NewSegment->valno = OldIdxVNI;
|
|
||||||
if (SlotIndex::isEarlierInstr(Next->start, NewIdx)) {
|
if (SlotIndex::isEarlierInstr(Next->start, NewIdx)) {
|
||||||
// There is no gap between NewSegment and its predecessor.
|
// There is no gap between NewSegment and its predecessor.
|
||||||
*NewSegment = LiveRange::Segment(Next->start, SplitPos,
|
*NewSegment = LiveRange::Segment(Next->start, SplitPos,
|
||||||
NewSegment->valno);
|
Next->valno);
|
||||||
NewSegment->valno->def = Next->start;
|
*Next = LiveRange::Segment(SplitPos, Next->end, OldIdxVNI);
|
||||||
|
|
||||||
*Next = LiveRange::Segment(SplitPos, Next->end, Next->valno);
|
|
||||||
Next->valno->def = SplitPos;
|
Next->valno->def = SplitPos;
|
||||||
} else {
|
} else {
|
||||||
// There is a gap between NewSegment and its predecessor
|
// There is a gap between NewSegment and its predecessor
|
||||||
// Value becomes live in.
|
// Value becomes live in.
|
||||||
*NewSegment = LiveRange::Segment(SplitPos, Next->start,
|
*NewSegment = LiveRange::Segment(SplitPos, Next->start, OldIdxVNI);
|
||||||
NewSegment->valno);
|
|
||||||
NewSegment->valno->def = SplitPos;
|
NewSegment->valno->def = SplitPos;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -109,8 +109,8 @@ private:
|
||||||
* update affected liveness intervals with LiveIntervalAnalysis::handleMove().
|
* update affected liveness intervals with LiveIntervalAnalysis::handleMove().
|
||||||
*/
|
*/
|
||||||
static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
|
static void testHandleMove(MachineFunction &MF, LiveIntervals &LIS,
|
||||||
unsigned From, unsigned To) {
|
unsigned From, unsigned To, unsigned BlockNum = 0) {
|
||||||
MachineBasicBlock &MBB = MF.front();
|
MachineBasicBlock &MBB = *MF.getBlockNumbered(BlockNum);
|
||||||
|
|
||||||
unsigned I = 0;
|
unsigned I = 0;
|
||||||
MachineInstr *FromInstr = nullptr;
|
MachineInstr *FromInstr = nullptr;
|
||||||
|
@ -307,6 +307,28 @@ TEST(LiveIntervalTest, MoveUndefUse) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(LiveIntervalTest, MoveUpValNos) {
|
||||||
|
// handleMoveUp() had a bug where it would reuse the value number of the
|
||||||
|
// destination segment, even though we have no guarntee that this valno wasn't
|
||||||
|
// used in other segments.
|
||||||
|
liveIntervalTest(
|
||||||
|
" successors: %bb.1, %bb.2\n"
|
||||||
|
" %0 = IMPLICIT_DEF\n"
|
||||||
|
" JG_1 %bb.2, implicit %eflags\n"
|
||||||
|
" JMP_1 %bb.1\n"
|
||||||
|
" bb.2:\n"
|
||||||
|
" NOOP implicit %0\n"
|
||||||
|
" bb.1:\n"
|
||||||
|
" successors: %bb.2\n"
|
||||||
|
" %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||||
|
" %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||||
|
" %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||||
|
" JMP_1 %bb.2\n",
|
||||||
|
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||||
|
testHandleMove(MF, LIS, 2, 0, 2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
initLLVM();
|
initLLVM();
|
||||||
|
|
Loading…
Reference in New Issue