Never clear <undef> flags on already joined copies.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 17 May 2012 18:32:42 +0000 (18:32 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 17 May 2012 18:32:42 +0000 (18:32 +0000)
RegisterCoalescer set <undef> flags on all operands of copy instructions
that are scheduled to be removed. This is so they won't affect
shrinkToUses() by introducing false register reads.

Make sure those <undef> flags are never cleared, or shrinkToUses() could
cause live intervals to end at instructions about to be deleted.

This would be a lot simpler if RegisterCoalescer could just erase joined
copies immediately instead of keeping all the to-be-deleted instructions
around.

This fixes PR12862. Unfortunately, bugpoint can't create a sane test
case for this. Like many other coalescer problems, this failure depends
of a very fragile series of events.

<rdar://problem/11474428>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157001 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegisterCoalescer.cpp

index f8794894d99b22ecfa6318d66a3c625db5d08d17..8dfd1b3fc854c2ffe52b5f67cc8e06bdadbd8854 100644 (file)
@@ -918,6 +918,8 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
 
   for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(SrcReg);
        MachineInstr *UseMI = I.skipInstruction();) {
+    bool AlreadyJoined = JoinedCopies.count(UseMI);
+
     // A PhysReg copy that won't be coalesced can perhaps be rematerialized
     // instead.
     if (DstIsPhys) {
@@ -925,7 +927,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
           UseMI->getOperand(1).getReg() == SrcReg &&
           UseMI->getOperand(0).getReg() != SrcReg &&
           UseMI->getOperand(0).getReg() != DstReg &&
-          !JoinedCopies.count(UseMI) &&
+          !AlreadyJoined &&
           reMaterializeTrivialDef(LIS->getInterval(SrcReg), false,
                                   UseMI->getOperand(0).getReg(), UseMI))
         continue;
@@ -937,7 +939,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
 
     // If SrcReg wasn't read, it may still be the case that DstReg is live-in
     // because SrcReg is a sub-register.
-    if (!Reads && SubIdx)
+    if (!Reads && SubIdx && !AlreadyJoined)
       Reads = DstInt.liveAt(LIS->getInstructionIndex(UseMI));
 
     // Replace SrcReg with DstReg in all UseMI operands.
@@ -947,7 +949,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
       // Adjust <undef> flags in case of sub-register joins. We don't want to
       // turn a full def into a read-modify-write sub-register def and vice
       // versa.
-      if (SubIdx && MO.isDef())
+      if (SubIdx && !AlreadyJoined && MO.isDef())
         MO.setIsUndef(!Reads);
 
       if (DstIsPhys)
@@ -957,7 +959,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
     }
 
     // This instruction is a copy that will be removed.
-    if (JoinedCopies.count(UseMI))
+    if (AlreadyJoined)
       continue;
 
     DEBUG({