From 71d3b895ba9f5cd970a1b7bd685c4482c03995f0 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 27 Apr 2011 17:42:31 +0000 Subject: [PATCH] Also add operands for defined and dead super-registers when rewriting. We cannot rely on the operands added by LiveIntervals in all cases as demonstrated by the test case. llvm-svn: 130313 --- llvm/lib/CodeGen/VirtRegMap.cpp | 21 +++++++++++++++------ llvm/test/CodeGen/ARM/crash-greedy.ll | 25 ++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp index 7a7ea69e27fc..226b78f7bcbd 100644 --- a/llvm/lib/CodeGen/VirtRegMap.cpp +++ b/llvm/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/llvm/test/CodeGen/ARM/crash-greedy.ll b/llvm/test/CodeGen/ARM/crash-greedy.ll index 0b229b27d2d4..8a865e23d0a4 100644 --- a/llvm/test/CodeGen/ARM/crash-greedy.ll +++ b/llvm/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 +}