diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 7a7ea69e27f..226b78f7bcb 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 SuperDeads; + SmallVector SuperDefs; SmallVector 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 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 - // 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 0b229b27d2d..8a865e23d0a 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 = COPY %vreg6:ssub_2; 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 +}