Fix PR7175. Insert copies of a REG_SEQUENCE source if it is used by other REG_SEQUENC...
authorEvan Cheng <evan.cheng@apple.com>
Mon, 17 May 2010 23:24:12 +0000 (23:24 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 17 May 2010 23:24:12 +0000 (23:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103994 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TwoAddressInstructionPass.cpp
test/CodeGen/ARM/reg_sequence.ll

index 2d43fba4bfa2dc25ef4bd8e71978c81aaf23d040..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.
@@ -1261,7 +1273,9 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
       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.
index cc75a13436ab3f50c282312edb9c6cf4c70e02c7..f74f8da08640663245a4a389e7c84ba4e3f5973a 100644 (file)
@@ -229,6 +229,41 @@ bb14:                                             ; preds = %bb6
   ret i32 0
 }
 
+%0 = type { %1, %1, %1, %1 }
+%1 = type { %2 }
+%2 = type { <4 x float> }
+%3 = type { %0, %1 }
+
+; PR7157
+define arm_aapcs_vfpcc float @t9(%0* nocapture, %3* nocapture) nounwind {
+; CHECK:        t9:
+; CHECK:        vldr.64
+; CHECK-NEXT:   vstmia r0, {d0,d1}
+; CHECK-NEXT:   vmov.i8 d1
+; CHECK-NEXT:   vstmia r0, {d0,d1}
+  %3 = bitcast double 0.000000e+00 to <2 x float> ; <<2 x float>> [#uses=2]
+  %4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x float>> [#uses=1]
+  store <4 x float> %4, <4 x float>* undef, align 16
+  %5 = shufflevector <2 x float> %3, <2 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x float>> [#uses=1]
+  store <4 x float> %5, <4 x float>* undef, align 16
+  br label %8
+
+; <label>:6                                       ; preds = %8
+  br i1 undef, label %7, label %10
+
+; <label>:7                                       ; preds = %6
+  br label %8
+
+; <label>:8                                       ; preds = %7, %2
+  br i1 undef, label %6, label %9
+
+; <label>:9                                       ; preds = %8
+  ret float undef
+
+; <label>:10                                      ; preds = %6
+  ret float 9.990000e+02
+}
+
 declare <4 x i32> @llvm.arm.neon.vld1.v4i32(i8*) nounwind readonly
 
 declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*) nounwind readonly