RegScavenger should not exclude undef uses
authorHal Finkel <hfinkel@anl.gov>
Thu, 11 Jul 2013 05:55:57 +0000 (05:55 +0000)
committerHal Finkel <hfinkel@anl.gov>
Thu, 11 Jul 2013 05:55:57 +0000 (05:55 +0000)
When computing currently-live registers, the register scavenger excludes undef
uses. As a result, undef uses are ignored when computing the restore points of
registers spilled into the emergency slots. While the register scavenger
normally excludes from consideration, when scavenging, registers used by the
current instruction, we need to not exclude undef uses. Otherwise, we might end
up requiring more emergency spill slots than we have (in the case where the
undef use *is* the currently-spilled register).

Another bug found by llvm-stress.

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

lib/CodeGen/RegisterScavenging.cpp
test/CodeGen/PowerPC/rs-undef-use.ll [new file with mode: 0644]

index d1a945df81a2332e96c895b02cf7543c2140d47a..75ebdaa357f789754ba6a96999b4f103c26644eb 100644 (file)
@@ -368,7 +368,7 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
   // Exclude all the registers being used by the instruction.
   for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
     MachineOperand &MO = I->getOperand(i);
-    if (MO.isReg() && MO.getReg() != 0 &&
+    if (MO.isReg() && MO.getReg() != 0 && !(MO.isUse() && MO.isUndef()) &&
         !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
       Candidates.reset(MO.getReg());
   }
diff --git a/test/CodeGen/PowerPC/rs-undef-use.ll b/test/CodeGen/PowerPC/rs-undef-use.ll
new file mode 100644 (file)
index 0000000..24dd5fd
--- /dev/null
@@ -0,0 +1,48 @@
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 < %s
+target triple = "powerpc64-unknown-linux-gnu"
+
+define void @autogen_SD156869(i8*, i64*) {
+BB:
+  %A3 = alloca <2 x i1>
+  %A2 = alloca <8 x i32>
+  br label %CF
+
+CF:                                               ; preds = %CF85, %CF, %BB
+  br i1 undef, label %CF, label %CF82.critedge
+
+CF82.critedge:                                    ; preds = %CF
+  store i8 -59, i8* %0
+  br label %CF82
+
+CF82:                                             ; preds = %CF82, %CF82.critedge
+  %L17 = load i8* %0
+  %E18 = extractelement <2 x i64> undef, i32 0
+  %PC = bitcast <2 x i1>* %A3 to i64*
+  br i1 undef, label %CF82, label %CF84.critedge
+
+CF84.critedge:                                    ; preds = %CF82
+  store i64 455385, i64* %PC
+  br label %CF84
+
+CF84:                                             ; preds = %CF84, %CF84.critedge
+  %L40 = load i64* %PC
+  store i64 -1, i64* %PC
+  %Sl46 = select i1 undef, i1 undef, i1 false
+  br i1 %Sl46, label %CF84, label %CF85
+
+CF85:                                             ; preds = %CF84
+  %L47 = load i64* %PC
+  store i64 %E18, i64* %PC
+  %PC52 = bitcast <8 x i32>* %A2 to ppc_fp128*
+  store ppc_fp128 0xM4D436562A0416DE00000000000000000, ppc_fp128* %PC52
+  %PC59 = bitcast i64* %1 to i8*
+  %Cmp61 = icmp slt i64 %L47, %L40
+  br i1 %Cmp61, label %CF, label %CF77
+
+CF77:                                             ; preds = %CF77, %CF85
+  br i1 undef, label %CF77, label %CF81
+
+CF81:                                             ; preds = %CF77
+  store i8 %L17, i8* %PC59
+  ret void
+}