diff options
-rw-r--r-- | include/llvm/CodeGen/LiveVariables.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/LiveVariables.cpp | 28 | ||||
-rw-r--r-- | test/CodeGen/X86/pr3243.ll | 15 |
3 files changed, 31 insertions, 14 deletions
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 0d932cf198..bb050f2603 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -146,7 +146,7 @@ private: // Intermediate data structures /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the /// uses. Pay special attention to the sub-register uses which may come below /// the last use of the whole register. - bool HandlePhysRegKill(unsigned Reg); + bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI); void HandlePhysRegUse(unsigned Reg, MachineInstr *MI); void HandlePhysRegDef(unsigned Reg, MachineInstr *MI); diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index ecfebc5511..a7bdbd92ff 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/lib/CodeGen/LiveVariables.cpp @@ -335,7 +335,7 @@ bool LiveVariables::hasRegisterUseBelow(unsigned Reg, return true; } -bool LiveVariables::HandlePhysRegKill(unsigned Reg) { +bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) { if (!PhysRegUse[Reg] && !PhysRegDef[Reg]) return false; @@ -373,8 +373,10 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg) { } } } - if (LastRefOrPartRef == PhysRegDef[Reg]) - // Not used at all. + + if (LastRefOrPartRef == PhysRegDef[Reg] && LastRefOrPartRef != MI) + // If the last reference is the last def, then it's not used at all. + // That is, unless we are currently processing the last reference itself. LastRefOrPartRef->addRegisterDead(Reg, TRI, true); /* Partial uses. Mark register def dead and add implicit def of @@ -427,14 +429,14 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) { // Start from the largest piece, find the last time any part of the register // is referenced. - if (!HandlePhysRegKill(Reg)) { + if (!HandlePhysRegKill(Reg, MI)) { // Only some of the sub-registers are used. for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) { if (!Live.count(SubReg)) // Skip if this sub-register isn't defined. continue; - if (HandlePhysRegKill(SubReg)) { + if (HandlePhysRegKill(SubReg, MI)) { Live.erase(SubReg); for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS) Live.erase(*SS); @@ -475,7 +477,7 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) { } } else { // Otherwise, the super register is killed. - if (HandlePhysRegKill(SuperReg)) { + if (HandlePhysRegKill(SuperReg, MI)) { PhysRegDef[SuperReg] = NULL; PhysRegUse[SuperReg] = NULL; for (const unsigned *SS = TRI->getSubRegisters(SuperReg); *SS; ++SS) { @@ -558,13 +560,13 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { SmallVector<unsigned, 4> DefRegs; for (unsigned i = 0; i != NumOperandsToProcess; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.getReg()) { - unsigned MOReg = MO.getReg(); - if (MO.isUse()) - UseRegs.push_back(MOReg); - if (MO.isDef()) - DefRegs.push_back(MOReg); - } + if (!MO.isReg() || MO.getReg() == 0) + continue; + unsigned MOReg = MO.getReg(); + if (MO.isUse()) + UseRegs.push_back(MOReg); + if (MO.isDef()) + DefRegs.push_back(MOReg); } // Process all uses. diff --git a/test/CodeGen/X86/pr3243.ll b/test/CodeGen/X86/pr3243.ll new file mode 100644 index 0000000000..7be887b38e --- /dev/null +++ b/test/CodeGen/X86/pr3243.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -march=x86 +; PR3243 + +declare signext i16 @safe_mul_func_int16_t_s_s(i16 signext, i32) nounwind readnone optsize + +define i32 @func_120(i32 %p_121) nounwind optsize { +entry: + %0 = trunc i32 %p_121 to i16 ; <i16> [#uses=1] + %1 = urem i16 %0, -15461 ; <i16> [#uses=1] + %phitmp1 = trunc i16 %1 to i8 ; <i8> [#uses=1] + %phitmp2 = urem i8 %phitmp1, -1 ; <i8> [#uses=1] + %phitmp3 = zext i8 %phitmp2 to i16 ; <i16> [#uses=1] + %2 = tail call signext i16 @safe_mul_func_int16_t_s_s(i16 signext %phitmp3, i32 1) nounwind ; <i16> [#uses=0] + unreachable +} |