aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp10
-rw-r--r--test/CodeGen/X86/jump_sign.ll16
2 files changed, 23 insertions, 3 deletions
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 69493bc207..89a57b53f3 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/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/test/CodeGen/X86/jump_sign.ll b/test/CodeGen/X86/jump_sign.ll
index 5fb6ee5254..61792d3253 100644
--- a/test/CodeGen/X86/jump_sign.ll
+++ b/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
+}