Skip to content

Commit 62ec024

Browse files
committedDec 21, 2018
[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
1 parent d914174 commit 62ec024

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed
 

‎llvm/lib/Target/X86/X86InstrInfo.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -3455,7 +3455,9 @@ inline static bool isRedundantFlagInstr(const MachineInstr &FlagI,
34553455

34563456
/// Check whether the definition can be converted
34573457
/// to remove a comparison against zero.
3458-
inline static bool isDefConvertible(const MachineInstr &MI) {
3458+
inline static bool isDefConvertible(const MachineInstr &MI, bool &NoSignFlag) {
3459+
NoSignFlag = false;
3460+
34593461
switch (MI.getOpcode()) {
34603462
default: return false;
34613463

@@ -3520,8 +3522,6 @@ inline static bool isDefConvertible(const MachineInstr &MI) {
35203522
case X86::SHL8r1: case X86::SHL16r1: case X86::SHL32r1:case X86::SHL64r1:
35213523
case X86::ANDN32rr: case X86::ANDN32rm:
35223524
case X86::ANDN64rr: case X86::ANDN64rm:
3523-
case X86::BEXTR32rr: case X86::BEXTR64rr:
3524-
case X86::BEXTR32rm: case X86::BEXTR64rm:
35253525
case X86::BLSI32rr: case X86::BLSI32rm:
35263526
case X86::BLSI64rr: case X86::BLSI64rm:
35273527
case X86::BLSMSK32rr:case X86::BLSMSK32rm:
@@ -3539,8 +3539,6 @@ inline static bool isDefConvertible(const MachineInstr &MI) {
35393539
case X86::TZCNT16rr: case X86::TZCNT16rm:
35403540
case X86::TZCNT32rr: case X86::TZCNT32rm:
35413541
case X86::TZCNT64rr: case X86::TZCNT64rm:
3542-
case X86::BEXTRI32ri: case X86::BEXTRI32mi:
3543-
case X86::BEXTRI64ri: case X86::BEXTRI64mi:
35443542
case X86::BLCFILL32rr: case X86::BLCFILL32rm:
35453543
case X86::BLCFILL64rr: case X86::BLCFILL64rm:
35463544
case X86::BLCI32rr: case X86::BLCI32rm:
@@ -3560,6 +3558,13 @@ inline static bool isDefConvertible(const MachineInstr &MI) {
35603558
case X86::TZMSK32rr: case X86::TZMSK32rm:
35613559
case X86::TZMSK64rr: case X86::TZMSK64rm:
35623560
return true;
3561+
case X86::BEXTR32rr: case X86::BEXTR64rr:
3562+
case X86::BEXTR32rm: case X86::BEXTR64rm:
3563+
case X86::BEXTRI32ri: case X86::BEXTRI32mi:
3564+
case X86::BEXTRI64ri: case X86::BEXTRI64mi:
3565+
// BEXTR doesn't update the sign flag so we can't use it.
3566+
NoSignFlag = true;
3567+
return true;
35633568
}
35643569
}
35653570

@@ -3662,8 +3667,9 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
36623667
// instruction we can eliminate the compare iff the use sets EFLAGS in the
36633668
// right way.
36643669
bool ShouldUpdateCC = false;
3670+
bool NoSignFlag = false;
36653671
X86::CondCode NewCC = X86::COND_INVALID;
3666-
if (IsCmpZero && !isDefConvertible(*MI)) {
3672+
if (IsCmpZero && !isDefConvertible(*MI, NoSignFlag)) {
36673673
// Scan forward from the use until we hit the use we're looking for or the
36683674
// compare instruction.
36693675
for (MachineBasicBlock::iterator J = MI;; ++J) {
@@ -3782,6 +3788,12 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
37823788
case X86::COND_O: case X86::COND_NO:
37833789
// CF and OF are used, we can't perform this optimization.
37843790
return false;
3791+
case X86::COND_S: case X86::COND_NS:
3792+
// If SF is used, but the instruction doesn't update the SF, then we
3793+
// can't do the optimization.
3794+
if (NoSignFlag)
3795+
return false;
3796+
break;
37853797
}
37863798

37873799
// If we're updating the condition code check if we have to reverse the

‎llvm/test/CodeGen/X86/bmi.ll

+2
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,7 @@ define void @pr40060(i32, i32) {
10321032
; X86: # %bb.0:
10331033
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
10341034
; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax
1035+
; X86-NEXT: testl %eax, %eax
10351036
; X86-NEXT: js .LBB45_1
10361037
; X86-NEXT: # %bb.2:
10371038
; X86-NEXT: jmp bar # TAILCALL
@@ -1041,6 +1042,7 @@ define void @pr40060(i32, i32) {
10411042
; X64-LABEL: pr40060:
10421043
; X64: # %bb.0:
10431044
; X64-NEXT: bextrl %esi, %edi, %eax
1045+
; X64-NEXT: testl %eax, %eax
10441046
; X64-NEXT: js .LBB45_1
10451047
; X64-NEXT: # %bb.2:
10461048
; X64-NEXT: jmp bar # TAILCALL

0 commit comments

Comments
 (0)