summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorManman Ren <mren@apple.com>2012-07-28 03:15:46 +0000
committerManman Ren <mren@apple.com>2012-07-28 03:15:46 +0000
commit32367c063b1578aa29cef33736064f77ee72602e (patch)
tree326394b196fa0a1c612fb938055746e4991fe5dd /llvm
parenta83aaa0da42a4dbfa620237de01cd200109967f6 (diff)
downloadbcm5719-llvm-32367c063b1578aa29cef33736064f77ee72602e.tar.gz
bcm5719-llvm-32367c063b1578aa29cef33736064f77ee72602e.zip
X86 Peephole: fix PR13475 in optimizeCompare.
It is possible that an instruction can use and update EFLAGS. When checking the safety, we should check the usage of EFLAGS first before declaring it is safe to optimize due to the update. llvm-svn: 160912
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp10
-rw-r--r--llvm/test/CodeGen/X86/jump_sign.ll16
2 files changed, 23 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 69493bc2070..89a57b53f3c 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -3221,12 +3221,15 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
MachineBasicBlock::iterator E = CmpInstr->getParent()->end();
for (++I; I != E; ++I) {
const MachineInstr &Instr = *I;
- if (Instr.modifiesRegister(X86::EFLAGS, TRI)) {
+ bool ModifyEFLAGS = Instr.modifiesRegister(X86::EFLAGS, TRI);
+ bool UseEFLAGS = Instr.readsRegister(X86::EFLAGS, TRI);
+ // We should check the usage if this instruction uses and updates EFLAGS.
+ if (!UseEFLAGS && ModifyEFLAGS) {
// It is safe to remove CmpInstr if EFLAGS is updated again.
IsSafe = true;
break;
}
- if (!Instr.readsRegister(X86::EFLAGS, TRI))
+ if (!UseEFLAGS && !ModifyEFLAGS)
continue;
// EFLAGS is used by this instruction.
@@ -3281,7 +3284,8 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
// instructions will be modified.
OpsToUpdate.push_back(std::make_pair(&*I, NewOpc));
}
- if (Instr.killsRegister(X86::EFLAGS, TRI)) {
+ if (ModifyEFLAGS || Instr.killsRegister(X86::EFLAGS, TRI)) {
+ // It is safe to remove CmpInstr if EFLAGS is updated again or killed.
IsSafe = true;
break;
}
diff --git a/llvm/test/CodeGen/X86/jump_sign.ll b/llvm/test/CodeGen/X86/jump_sign.ll
index 5fb6ee52548..61792d3253c 100644
--- a/llvm/test/CodeGen/X86/jump_sign.ll
+++ b/llvm/test/CodeGen/X86/jump_sign.ll
@@ -214,3 +214,19 @@ entry:
%add. = select i1 %cmp, i32 %add, i32 0
ret i32 %add.
}
+; PR13475
+; If we have sub a, b and cmp b, a and the result of cmp is used
+; by sbb, we should not optimize cmp away.
+define i32 @q(i32 %j.4, i32 %w, i32 %el) {
+; CHECK: q:
+; CHECK: sub
+; CHECK: cmp
+; CHECK-NEXT: sbb
+ %tmp532 = add i32 %j.4, %w
+ %tmp533 = icmp ugt i32 %tmp532, %el
+ %tmp534 = icmp ult i32 %w, %el
+ %or.cond = and i1 %tmp533, %tmp534
+ %tmp535 = sub i32 %el, %w
+ %j.5 = select i1 %or.cond, i32 %tmp535, i32 %j.4
+ ret i32 %j.5
+}
OpenPOWER on IntegriCloud