diff options
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 10 | ||||
-rw-r--r-- | test/CodeGen/X86/jump_sign.ll | 16 |
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 +} |