[llvm] 2328cab - [X86] Prevent LowerSELECT from causing suboptimal codegen for __builtin_ffs(X) - 1.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 11:47:47 PDT 2020
Author: Craig Topper
Date: 2020-06-08T11:46:56-07:00
New Revision: 2328cab16ccd8f17fee782c29fb844662c089fbb
URL: https://github.com/llvm/llvm-project/commit/2328cab16ccd8f17fee782c29fb844662c089fbb
DIFF: https://github.com/llvm/llvm-project/commit/2328cab16ccd8f17fee782c29fb844662c089fbb.diff
LOG: [X86] Prevent LowerSELECT from causing suboptimal codegen for __builtin_ffs(X) - 1.
LowerSELECT sees the CMP with 0 and wants to use a trick with SUB
and SBB. But we can use the flags from the BSF/TZCNT.
Fixes PR46203.
Differential Revision: https://reviews.llvm.org/D81312
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/dagcombine-select.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b194423a8371..fe06bb8b3e5f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22851,12 +22851,25 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
Cond.getOperand(1).getOpcode() == X86ISD::CMP &&
isNullConstant(Cond.getOperand(1).getOperand(1))) {
SDValue Cmp = Cond.getOperand(1);
+ SDValue CmpOp0 = Cmp.getOperand(0);
unsigned CondCode = Cond.getConstantOperandVal(0);
- if ((isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
+ // Special handling for __builtin_ffs(X) - 1 pattern which looks like
+ // (select (seteq X, 0), -1, (cttz_zero_undef X)). Disable the special
+ // handle to keep the CMP with 0. This should be removed by
+ // optimizeCompareInst by using the flags from the BSR/TZCNT used for the
+ // cttz_zero_undef.
+ auto MatchFFSMinus1 = [&](SDValue Op1, SDValue Op2) {
+ return (Op1.getOpcode() == ISD::CTTZ_ZERO_UNDEF && Op1.hasOneUse() &&
+ Op1.getOperand(0) == CmpOp0 && isAllOnesConstant(Op2));
+ };
+ if (Subtarget.hasCMov() && (VT == MVT::i32 || VT == MVT::i64) &&
+ ((CondCode == X86::COND_NE && MatchFFSMinus1(Op1, Op2)) ||
+ (CondCode == X86::COND_E && MatchFFSMinus1(Op2, Op1)))) {
+ // Keep Cmp.
+ } else if ((isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
(CondCode == X86::COND_E || CondCode == X86::COND_NE)) {
SDValue Y = isAllOnesConstant(Op2) ? Op1 : Op2;
- SDValue CmpOp0 = Cmp.getOperand(0);
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
SDVTList CmpVTs = DAG.getVTList(CmpOp0.getValueType(), MVT::i32);
@@ -22886,7 +22899,6 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
} else if (!Subtarget.hasCMov() && CondCode == X86::COND_E &&
Cmp.getOperand(0).getOpcode() == ISD::AND &&
isOneConstant(Cmp.getOperand(0).getOperand(1))) {
- SDValue CmpOp0 = Cmp.getOperand(0);
SDValue Src1, Src2;
// true if Op2 is XOR or OR operator and one of its operands
// is equal to Op1
diff --git a/llvm/test/CodeGen/X86/dagcombine-select.ll b/llvm/test/CodeGen/X86/dagcombine-select.ll
index a6a81b975705..ff022c3bf0fa 100644
--- a/llvm/test/CodeGen/X86/dagcombine-select.ll
+++ b/llvm/test/CodeGen/X86/dagcombine-select.ll
@@ -436,19 +436,15 @@ define i32 @cttz_32_eq_select_ffs_m1(i32 %v) nounwind {
; NOBMI-LABEL: cttz_32_eq_select_ffs_m1:
; NOBMI: # %bb.0:
; NOBMI-NEXT: bsfl %edi, %ecx
-; NOBMI-NEXT: xorl %eax, %eax
-; NOBMI-NEXT: cmpl $1, %edi
-; NOBMI-NEXT: sbbl %eax, %eax
-; NOBMI-NEXT: orl %ecx, %eax
+; NOBMI-NEXT: movl $-1, %eax
+; NOBMI-NEXT: cmovnel %ecx, %eax
; NOBMI-NEXT: retq
;
; BMI-LABEL: cttz_32_eq_select_ffs_m1:
; BMI: # %bb.0:
; BMI-NEXT: tzcntl %edi, %ecx
-; BMI-NEXT: xorl %eax, %eax
-; BMI-NEXT: cmpl $1, %edi
-; BMI-NEXT: sbbl %eax, %eax
-; BMI-NEXT: orl %ecx, %eax
+; BMI-NEXT: movl $-1, %eax
+; BMI-NEXT: cmovael %ecx, %eax
; BMI-NEXT: retq
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
@@ -461,19 +457,15 @@ define i32 @cttz_32_ne_select_ffs_m1(i32 %v) nounwind {
; NOBMI-LABEL: cttz_32_ne_select_ffs_m1:
; NOBMI: # %bb.0:
; NOBMI-NEXT: bsfl %edi, %ecx
-; NOBMI-NEXT: xorl %eax, %eax
-; NOBMI-NEXT: cmpl $1, %edi
-; NOBMI-NEXT: sbbl %eax, %eax
-; NOBMI-NEXT: orl %ecx, %eax
+; NOBMI-NEXT: movl $-1, %eax
+; NOBMI-NEXT: cmovnel %ecx, %eax
; NOBMI-NEXT: retq
;
; BMI-LABEL: cttz_32_ne_select_ffs_m1:
; BMI: # %bb.0:
; BMI-NEXT: tzcntl %edi, %ecx
-; BMI-NEXT: xorl %eax, %eax
-; BMI-NEXT: cmpl $1, %edi
-; BMI-NEXT: sbbl %eax, %eax
-; BMI-NEXT: orl %ecx, %eax
+; BMI-NEXT: movl $-1, %eax
+; BMI-NEXT: cmovael %ecx, %eax
; BMI-NEXT: retq
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
More information about the llvm-commits
mailing list