Fix PR7175. Insert copies of a REG_SEQUENCE source if it is used by other REG_SEQUENC...
[oota-llvm.git] / lib / CodeGen / TwoAddressInstructionPass.cpp
index fb9bddca25c082f5b4a9e60ffae74924c7b9d7d9..fdecc5f14af60421de2e05a0dd20985f4f01f31c 100644 (file)
@@ -134,6 +134,7 @@ namespace {
     /// of the de-ssa process. This replaces sources of REG_SEQUENCE as
     /// sub-register references of the register defined by REG_SEQUENCE.
     bool EliminateRegSequences();
+
   public:
     static char ID; // Pass identification, replacement for typeid
     TwoAddressInstructionPass() : MachineFunctionPass(&ID) {}
@@ -1216,6 +1217,17 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
   }
 }
 
+static bool HasOtherRegSequenceUses(unsigned Reg, MachineInstr *RegSeq,
+                                    MachineRegisterInfo *MRI) {
+  for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
+         UE = MRI->use_end(); UI != UE; ++UI) {
+    MachineInstr *UseMI = &*UI;
+    if (UseMI != RegSeq && UseMI->isRegSequence())
+      return true;
+  }
+  return false;
+}
+
 /// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as part
 /// of the de-ssa process. This replaces sources of REG_SEQUENCE as
 /// sub-register references of the register defined by REG_SEQUENCE. e.g.
@@ -1238,6 +1250,7 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
       llvm_unreachable(0);
     }
 
+    bool IsImpDef = true;
     SmallVector<unsigned, 4> RealSrcs;
     SmallSet<unsigned, 4> Seen;
     for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) {
@@ -1253,13 +1266,16 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
         DefMI->eraseFromParent();
         continue;
       }
+      IsImpDef = false;
 
       // Remember EXTRACT_SUBREG sources. These might be candidate for
       // coalescing.
       if (DefMI->isExtractSubreg())
         RealSrcs.push_back(DefMI->getOperand(1).getReg());
 
-      if (!Seen.insert(SrcReg) || MI->getParent() != DefMI->getParent()) {
+      if (!Seen.insert(SrcReg) ||
+          MI->getParent() != DefMI->getParent() ||
+          HasOtherRegSequenceUses(SrcReg, MI, MRI)) {
         // REG_SEQUENCE cannot have duplicated operands, add a copy.
         // Also add an copy if the source if live-in the block. We don't want
         // to end up with a partial-redef of a livein, e.g.
@@ -1297,8 +1313,15 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
       UpdateRegSequenceSrcs(SrcReg, DstReg, SubIdx, MRI);
     }
 
-    DEBUG(dbgs() << "Eliminated: " << *MI);
-    MI->eraseFromParent();
+    if (IsImpDef) {
+      DEBUG(dbgs() << "Turned: " << *MI << " into an IMPLICIT_DEF");
+      MI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF));
+      for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
+        MI->RemoveOperand(j);      
+    } else {
+      DEBUG(dbgs() << "Eliminated: " << *MI);
+      MI->eraseFromParent();
+    }
 
     // Try coalescing some EXTRACT_SUBREG instructions.
     CoalesceExtSubRegs(RealSrcs, DstReg);