aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/LiveVariables.h2
-rw-r--r--lib/CodeGen/LiveVariables.cpp28
-rw-r--r--test/CodeGen/X86/pr3243.ll15
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
+}