[llvm] r307471 - [x86] add SBB optimization for SETBE (ule) condition code

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 8 07:04:48 PDT 2017


Author: spatel
Date: Sat Jul  8 07:04:48 2017
New Revision: 307471

URL: http://llvm.org/viewvc/llvm-project?rev=307471&view=rev
Log:
[x86] add SBB optimization for SETBE (ule) condition code

x86 scalar select-of-constants (Cond ? C1 : C2) combining/lowering is a mess 
with missing optimizations. We handle some patterns, but miss logical variants.

To clean that up, we should convert all select-of-constants to logic/math and 
enhance the combining for the expected patterns from that. Selecting 0 or -1 
needs extra attention to produce the optimal code as shown here.

Attempt to verify that all of these IR forms are logically equivalent:
http://rise4fun.com/Alive/plxs

Earlier steps in this series:
rL306040
rL306072
rL307404 (D34652)

As acknowledged in the earlier review, there's a possibility that some Intel
uarch would prefer to produce an xor to clear the fake register operand with
sbb %eax, %eax. This will likely need to be addressed in a separate pass.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/CodeGen/X86/sbb.ll

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=307471&r1=307470&r2=307471&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Jul  8 07:04:48 2017
@@ -35027,7 +35027,19 @@ static SDValue combineAddOrSubToADCOrSBB
                          Y.getOperand(1));
     }
 
-    // TODO: Handle COND_BE if it was produced by X86ISD::SUB similar to below.
+    SDValue EFLAGS = Y->getOperand(1);
+    if (CC == X86::COND_BE && EFLAGS.getOpcode() == X86ISD::SUB &&
+        EFLAGS.hasOneUse() && EFLAGS.getValueType().isInteger() &&
+        !isa<ConstantSDNode>(EFLAGS.getOperand(1))) {
+      // Swap the operands of a SUB, and we have the same pattern as above.
+      // -1 + SETBE (SUB A, B) --> -1 + SETAE (SUB B, A) --> SBB %eax, %eax
+      SDValue NewSub =
+          DAG.getNode(X86ISD::SUB, SDLoc(EFLAGS), EFLAGS.getNode()->getVTList(),
+                      EFLAGS.getOperand(1), EFLAGS.getOperand(0));
+      SDValue NewEFLAGS = SDValue(NewSub.getNode(), EFLAGS.getResNo());
+      return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
+                         DAG.getConstant(X86::COND_B, DL, MVT::i8), NewEFLAGS);
+    }
   }
 
   if (CC == X86::COND_A) {

Modified: llvm/trunk/test/CodeGen/X86/sbb.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sbb.ll?rev=307471&r1=307470&r2=307471&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/sbb.ll (original)
+++ llvm/trunk/test/CodeGen/X86/sbb.ll Sat Jul  8 07:04:48 2017
@@ -161,10 +161,8 @@ define i32 @uge_select_0_or_neg1(i32 %x,
 define i32 @ule_select_0_or_neg1(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: ule_select_0_or_neg1:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl %edi, %esi
-; CHECK-NEXT:    setbe %al
-; CHECK-NEXT:    decl %eax
+; CHECK-NEXT:    cmpl %esi, %edi
+; CHECK-NEXT:    sbbl %eax, %eax
 ; CHECK-NEXT:    retq
   %cmp = icmp ule i32 %y, %x
   %ext = zext i1 %cmp to i32




More information about the llvm-commits mailing list