[PATCH] D81312: [X86] Prevent LowerSELECT from causing suboptimal codegen for __builtn_ffs(X) - 1.

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 12:10:02 PDT 2020


This revision was automatically updated to reflect the committed changes.
Closed by commit rG2328cab16ccd: [X86] Prevent LowerSELECT from causing suboptimal codegen for __builtin_ffs(X)… (authored by craig.topper).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81312/new/

https://reviews.llvm.org/D81312

Files:
  llvm/lib/Target/X86/X86ISelLowering.cpp
  llvm/test/CodeGen/X86/dagcombine-select.ll


Index: llvm/test/CodeGen/X86/dagcombine-select.ll
===================================================================
--- llvm/test/CodeGen/X86/dagcombine-select.ll
+++ llvm/test/CodeGen/X86/dagcombine-select.ll
@@ -436,19 +436,15 @@
 ; 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 @@
 ; 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)
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22851,12 +22851,25 @@
       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 @@
     } 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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81312.269309.patch
Type: text/x-patch
Size: 3713 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200608/089752af/attachment.bin>


More information about the llvm-commits mailing list