[PATCH] D34652: [x86] add SBB optimization for SETAE (uge) condition code

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 26 16:08:07 PDT 2017


spatel created this revision.
Herald added a subscriber: mcrosier.

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. DAGCombiner already has the foundation to allow the transforms, so we just need to fill in the holes for x86 math op lowering. 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:
https://reviews.llvm.org/rL306040
https://reviews.llvm.org/rL306072


https://reviews.llvm.org/D34652

Files:
  lib/Target/X86/X86ISelLowering.cpp
  test/CodeGen/X86/sbb.ll


Index: test/CodeGen/X86/sbb.ll
===================================================================
--- test/CodeGen/X86/sbb.ll
+++ test/CodeGen/X86/sbb.ll
@@ -146,10 +146,8 @@
 define i32 @uge_select_0_or_neg1(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: uge_select_0_or_neg1:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    cmpl %esi, %edi
-; CHECK-NEXT:    setae %al
-; CHECK-NEXT:    decl %eax
+; CHECK-NEXT:    sbbl %eax, %eax
 ; CHECK-NEXT:    retq
   %cmp = icmp uge i32 %x, %y
   %ext = zext i1 %cmp to i32
@@ -180,10 +178,8 @@
 define i32 @uge_select_0_or_neg1_sub(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: uge_select_0_or_neg1_sub:
 ; CHECK:       # BB#0:
-; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    cmpl %esi, %edi
-; CHECK-NEXT:    setae %al
-; CHECK-NEXT:    decl %eax
+; CHECK-NEXT:    sbbl %eax, %eax
 ; CHECK-NEXT:    retq
   %cmp = icmp uge i32 %x, %y
   %ext = zext i1 %cmp to i32
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -34866,6 +34866,21 @@
     return DAG.getNode(IsSub ? ISD::SUB : ISD::ADD, DL, VT, X, SBB);
   }
 
+  auto *ConstantX = dyn_cast<ConstantSDNode>(X);
+  if (!IsSub && ConstantX && ConstantX->isAllOnesValue()) {
+    if (CC == X86::COND_AE) {
+      // This is a complicated way to get -1 or 0 from the carry flag:
+      // -1 + SETAE --> -1 + (!CF) --> CF ? -1 : 0 --> SBB %eax, %eax
+      // We don't have to match the subtract equivalent because sub X, 1 is
+      // canonicalized to add X, -1.
+      return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
+                         DAG.getConstant(X86::COND_B, DL, MVT::i8),
+                         Y.getOperand(1));
+    }
+
+    // TODO: Handle COND_BE if it was produced by X86ISD::SUB similar to below.
+  }
+
   if (CC == X86::COND_A) {
     SDValue EFLAGS = Y->getOperand(1);
     // Try to convert COND_A into COND_B in an attempt to facilitate
@@ -34902,7 +34917,7 @@
 
   // If X is -1 or 0, then we have an opportunity to avoid constants required in
   // the general case below.
-  if (auto *ConstantX = dyn_cast<ConstantSDNode>(X)) {
+  if (ConstantX) {
     // 'neg' sets the carry flag when Z != 0, so create 0 or -1 using 'sbb' with
     // fake operands:
     //  0 - (Z != 0) --> sbb %eax, %eax, (neg Z)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34652.104035.patch
Type: text/x-patch
Size: 2395 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170626/d7cd68b9/attachment.bin>


More information about the llvm-commits mailing list