Rematerialization logic was overly conservative when it comes to loads from fixed...
authorEvan Cheng <evan.cheng@apple.com>
Sat, 23 Feb 2008 03:38:34 +0000 (03:38 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sat, 23 Feb 2008 03:38:34 +0000 (03:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47529 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveIntervalAnalysis.cpp
test/CodeGen/X86/2008-02-22-ReMatBug.ll [new file with mode: 0644]

index a18f36afb7f6774dc3b6c5b6857536cc9d766bcf..2ff8afdeb8ca5b09678e1be5395868d99a2e9e0f 100644 (file)
@@ -646,27 +646,9 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
 
   int FrameIdx = 0;
   if (tii_->isLoadFromStackSlot(MI, FrameIdx) &&
-      mf_->getFrameInfo()->isImmutableObjectIndex(FrameIdx)) {
-    // This is a load from fixed stack slot. It can be rematerialized unless
-    // it's re-defined by a two-address instruction.
-    isLoad = true;
-    for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
-         i != e; ++i) {
-      const VNInfo *VNI = *i;
-      if (VNI == ValNo)
-        continue;
-      unsigned DefIdx = VNI->def;
-      if (DefIdx == ~1U)
-        continue; // Dead val#.
-      MachineInstr *DefMI = (DefIdx == ~0u)
-        ? NULL : getInstructionFromIndex(DefIdx);
-      if (DefMI && DefMI->isRegReDefinedByTwoAddr(li.reg)) {
-        isLoad = false;
-        return false;
-      }
-    }
+      mf_->getFrameInfo()->isImmutableObjectIndex(FrameIdx))
+    // This is a load from fixed stack slot. It can be rematerialized.
     return true;
-  }
 
   if (tii_->isTriviallyReMaterializable(MI)) {
     isLoad = TID.isSimpleLoad();
@@ -754,6 +736,10 @@ bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI,
     FoldOps.push_back(OpIdx);
   }
 
+  // Can't fold a load from fixed stack slot into a two address instruction.
+  if (isSS && DefMI && (MRInfo & VirtRegMap::isMod))
+    return false;
+
   MachineInstr *fmi = isSS ? tii_->foldMemoryOperand(*mf_, MI, FoldOps, Slot)
                            : tii_->foldMemoryOperand(*mf_, MI, FoldOps, DefMI);
   if (fmi) {
diff --git a/test/CodeGen/X86/2008-02-22-ReMatBug.ll b/test/CodeGen/X86/2008-02-22-ReMatBug.ll
new file mode 100644 (file)
index 0000000..c26c19e
--- /dev/null
@@ -0,0 +1,49 @@
+; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of re-materialization} | grep 3
+; rdar://5761454
+
+       %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* }
+
+define fastcc %struct.quad_struct* @MakeTree(i32 %size, i32 %center_x, i32 %center_y, i32 %lo_proc, i32 %hi_proc, %struct.quad_struct* %parent, i32 %ct, i32 %level) nounwind  {
+entry:
+       br i1 true, label %bb43.i, label %bb.i
+
+bb.i:          ; preds = %entry
+       ret %struct.quad_struct* null
+
+bb43.i:                ; preds = %entry
+       br i1 true, label %CheckOutside.exit40.i, label %bb11.i38.i
+
+bb11.i38.i:            ; preds = %bb43.i
+       ret %struct.quad_struct* null
+
+CheckOutside.exit40.i:         ; preds = %bb43.i
+       br i1 true, label %CheckOutside.exit30.i, label %bb11.i28.i
+
+bb11.i28.i:            ; preds = %CheckOutside.exit40.i
+       ret %struct.quad_struct* null
+
+CheckOutside.exit30.i:         ; preds = %CheckOutside.exit40.i
+       br i1 true, label %CheckOutside.exit20.i, label %bb11.i18.i
+
+bb11.i18.i:            ; preds = %CheckOutside.exit30.i
+       ret %struct.quad_struct* null
+
+CheckOutside.exit20.i:         ; preds = %CheckOutside.exit30.i
+       br i1 true, label %bb34, label %bb11.i8.i
+
+bb11.i8.i:             ; preds = %CheckOutside.exit20.i
+       ret %struct.quad_struct* null
+
+bb34:          ; preds = %CheckOutside.exit20.i
+       %tmp15.reg2mem.0 = sdiv i32 %size, 2            ; <i32> [#uses=7]
+       %tmp85 = sub i32 %center_y, %tmp15.reg2mem.0            ; <i32> [#uses=2]
+       %tmp88 = sub i32 %center_x, %tmp15.reg2mem.0            ; <i32> [#uses=2]
+       %tmp92 = tail call fastcc %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 %tmp88, i32 %tmp85, i32 0, i32 %hi_proc, %struct.quad_struct* null, i32 2, i32 0 ) nounwind                 ; <%struct.quad_struct*> [#uses=0]
+       %tmp99 = add i32 0, %hi_proc            ; <i32> [#uses=1]
+       %tmp100 = sdiv i32 %tmp99, 2            ; <i32> [#uses=1]
+       %tmp110 = tail call fastcc %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 0, i32 %tmp85, i32 0, i32 %tmp100, %struct.quad_struct* null, i32 3, i32 0 ) nounwind              ; <%struct.quad_struct*> [#uses=0]
+       %tmp122 = add i32 %tmp15.reg2mem.0, %center_y           ; <i32> [#uses=2]
+       %tmp129 = tail call fastcc %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 0, i32 %tmp122, i32 0, i32 0, %struct.quad_struct* null, i32 1, i32 0 ) nounwind           ; <%struct.quad_struct*> [#uses=0]
+       %tmp147 = tail call fastcc %struct.quad_struct* @MakeTree( i32 %tmp15.reg2mem.0, i32 %tmp88, i32 %tmp122, i32 %lo_proc, i32 0, %struct.quad_struct* null, i32 0, i32 0 ) nounwind               ; <%struct.quad_struct*> [#uses=0]
+       unreachable
+}