summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-12-21 21:16:26 +0000
committerCraig Topper <craig.topper@intel.com>2018-12-21 21:16:26 +0000
commit62ec024d3bc7a5788aa982b5b9d1ea4455598b53 (patch)
treebdfcc9d388fc6963ecbaa7bf80684ba7ba5ac43d
parentd914174d9bd5ab3a5e6eb3f9ccc245df4d6fe5e6 (diff)
downloadbcm5719-llvm-62ec024d3bc7a5788aa982b5b9d1ea4455598b53.tar.gz
bcm5719-llvm-62ec024d3bc7a5788aa982b5b9d1ea4455598b53.zip
[X86] Don't allow optimizeCompareInstr to replace a CMP with BEXTR if the sign flag is used.
The BEXTR instruction documents the SF bit as undefined. The TBM BEXTR instruction has the same issue, but I'm not sure how to test it. With the control being an immediate we can determine the sign bit is 0 or the BEXTR would have been removed. Fixes PR40060 Differential Revision: https://reviews.llvm.org/D55807 llvm-svn: 349956
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp24
-rw-r--r--llvm/test/CodeGen/X86/bmi.ll2
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
OpenPOWER on IntegriCloud