aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/VirtRegMap.cpp21
-rw-r--r--test/CodeGen/ARM/crash-greedy.ll25
2 files changed, 39 insertions, 7 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index 7a7ea69e27..226b78f7bc 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -260,6 +260,8 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) {
<< "********** Function: "
<< MF->getFunction()->getName() << '\n');
DEBUG(dump());
+ SmallVector<unsigned, 8> SuperDeads;
+ SmallVector<unsigned, 8> SuperDefs;
SmallVector<unsigned, 8> SuperKills;
for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
@@ -283,12 +285,13 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) {
if (MO.getSubReg()) {
// A virtual register kill refers to the whole register, so we may
// have to add <imp-use,kill> operands for the super-register.
- if (MO.isUse() && MO.isKill() && !MO.isUndef())
- SuperKills.push_back(PhysReg);
-
- // We don't have to deal with sub-register defs because
- // LiveIntervalAnalysis already added the necessary <imp-def>
- // operands.
+ if (MO.isUse()) {
+ if (MO.isKill() && !MO.isUndef())
+ SuperKills.push_back(PhysReg);
+ } else if (MO.isDead())
+ SuperDeads.push_back(PhysReg);
+ else
+ SuperDefs.push_back(PhysReg);
// PhysReg operands cannot have subregister indexes.
PhysReg = TRI->getSubReg(PhysReg, MO.getSubReg());
@@ -305,6 +308,12 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) {
while (!SuperKills.empty())
MI->addRegisterKilled(SuperKills.pop_back_val(), TRI, true);
+ while (!SuperDeads.empty())
+ MI->addRegisterDead(SuperDeads.pop_back_val(), TRI, true);
+
+ while (!SuperDefs.empty())
+ MI->addRegisterDefined(SuperDefs.pop_back_val(), TRI);
+
DEBUG(dbgs() << "> " << *MI);
// Finally, remove any identity copies.
diff --git a/test/CodeGen/ARM/crash-greedy.ll b/test/CodeGen/ARM/crash-greedy.ll
index 0b229b27d2..8a865e23d0 100644
--- a/test/CodeGen/ARM/crash-greedy.ll
+++ b/test/CodeGen/ARM/crash-greedy.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -regalloc=greedy -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim | FileCheck %s
+; RUN: llc < %s -regalloc=greedy -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim -verify-machineinstrs | FileCheck %s
;
; ARM tests that crash or fail with the greedy register allocator.
@@ -59,3 +59,26 @@ for.end: ; preds = %cond.end
ret void
}
+; CHECK: insert_elem
+; This test has a sub-register copy with a kill flag:
+; %vreg6:ssub_3<def> = COPY %vreg6:ssub_2<kill>; QPR_VFP2:%vreg6
+; The rewriter must do something sensible with that, or the scavenger crashes.
+define void @insert_elem() nounwind {
+entry:
+ br i1 undef, label %if.end251, label %if.then84
+
+if.then84: ; preds = %entry
+ br i1 undef, label %if.end251, label %if.then195
+
+if.then195: ; preds = %if.then84
+ %div = fdiv float 1.000000e+00, undef
+ %vecinit207 = insertelement <4 x float> undef, float %div, i32 1
+ %vecinit208 = insertelement <4 x float> %vecinit207, float 1.000000e+00, i32 2
+ %vecinit209 = insertelement <4 x float> %vecinit208, float 1.000000e+00, i32 3
+ %mul216 = fmul <4 x float> zeroinitializer, %vecinit209
+ store <4 x float> %mul216, <4 x float>* undef, align 16
+ br label %if.end251
+
+if.end251: ; preds = %if.then195, %if.then84, %entry
+ ret void
+}