diff options
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 24 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/bmi.ll | 2 |
2 files changed, 20 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 40de049bfe8..ab14ee7fadf 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -3455,7 +3455,9 @@ inline static bool isRedundantFlagInstr(const MachineInstr &FlagI, /// Check whether the definition can be converted /// to remove a comparison against zero. -inline static bool isDefConvertible(const MachineInstr &MI) { +inline static bool isDefConvertible(const MachineInstr &MI, bool &NoSignFlag) { + NoSignFlag = false; + switch (MI.getOpcode()) { default: return false; @@ -3520,8 +3522,6 @@ inline static bool isDefConvertible(const MachineInstr &MI) { case X86::SHL8r1: case X86::SHL16r1: case X86::SHL32r1:case X86::SHL64r1: case X86::ANDN32rr: case X86::ANDN32rm: case X86::ANDN64rr: case X86::ANDN64rm: - case X86::BEXTR32rr: case X86::BEXTR64rr: - case X86::BEXTR32rm: case X86::BEXTR64rm: case X86::BLSI32rr: case X86::BLSI32rm: case X86::BLSI64rr: case X86::BLSI64rm: case X86::BLSMSK32rr:case X86::BLSMSK32rm: @@ -3539,8 +3539,6 @@ inline static bool isDefConvertible(const MachineInstr &MI) { case X86::TZCNT16rr: case X86::TZCNT16rm: case X86::TZCNT32rr: case X86::TZCNT32rm: case X86::TZCNT64rr: case X86::TZCNT64rm: - case X86::BEXTRI32ri: case X86::BEXTRI32mi: - case X86::BEXTRI64ri: case X86::BEXTRI64mi: case X86::BLCFILL32rr: case X86::BLCFILL32rm: case X86::BLCFILL64rr: case X86::BLCFILL64rm: case X86::BLCI32rr: case X86::BLCI32rm: @@ -3560,6 +3558,13 @@ inline static bool isDefConvertible(const MachineInstr &MI) { case X86::TZMSK32rr: case X86::TZMSK32rm: case X86::TZMSK64rr: case X86::TZMSK64rm: return true; + case X86::BEXTR32rr: case X86::BEXTR64rr: + case X86::BEXTR32rm: case X86::BEXTR64rm: + case X86::BEXTRI32ri: case X86::BEXTRI32mi: + case X86::BEXTRI64ri: case X86::BEXTRI64mi: + // BEXTR doesn't update the sign flag so we can't use it. + NoSignFlag = true; + return true; } } @@ -3662,8 +3667,9 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, // instruction we can eliminate the compare iff the use sets EFLAGS in the // right way. bool ShouldUpdateCC = false; + bool NoSignFlag = false; X86::CondCode NewCC = X86::COND_INVALID; - if (IsCmpZero && !isDefConvertible(*MI)) { + if (IsCmpZero && !isDefConvertible(*MI, NoSignFlag)) { // Scan forward from the use until we hit the use we're looking for or the // compare instruction. for (MachineBasicBlock::iterator J = MI;; ++J) { @@ -3782,6 +3788,12 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, case X86::COND_O: case X86::COND_NO: // CF and OF are used, we can't perform this optimization. return false; + case X86::COND_S: case X86::COND_NS: + // If SF is used, but the instruction doesn't update the SF, then we + // can't do the optimization. + if (NoSignFlag) + return false; + break; } // If we're updating the condition code check if we have to reverse the diff --git a/llvm/test/CodeGen/X86/bmi.ll b/llvm/test/CodeGen/X86/bmi.ll index 03d6df03c31..ee7cf5f6bc6 100644 --- a/llvm/test/CodeGen/X86/bmi.ll +++ b/llvm/test/CodeGen/X86/bmi.ll @@ -1032,6 +1032,7 @@ define void @pr40060(i32, i32) { ; X86: # %bb.0: ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax +; X86-NEXT: testl %eax, %eax ; X86-NEXT: js .LBB45_1 ; X86-NEXT: # %bb.2: ; X86-NEXT: jmp bar # TAILCALL @@ -1041,6 +1042,7 @@ define void @pr40060(i32, i32) { ; X64-LABEL: pr40060: ; X64: # %bb.0: ; X64-NEXT: bextrl %esi, %edi, %eax +; X64-NEXT: testl %eax, %eax ; X64-NEXT: js .LBB45_1 ; X64-NEXT: # %bb.2: ; X64-NEXT: jmp bar # TAILCALL |

