[llvm] e745507 - [x86] exclude "X==0 ? Y :-1" from math/logic transform

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 9 06:07:48 PST 2022


Author: Sanjay Patel
Date: 2022-01-09T09:03:39-05:00
New Revision: e745507eda2704e913cdde5ba9211d969d87b95e

URL: https://github.com/llvm/llvm-project/commit/e745507eda2704e913cdde5ba9211d969d87b95e
DIFF: https://github.com/llvm/llvm-project/commit/e745507eda2704e913cdde5ba9211d969d87b95e.diff

LOG: [x86] exclude "X==0 ? Y :-1" from math/logic transform

This is the last step in a series to improve lowering
via "SBB" asm:
68defc0134
aab1f55e33
...and fixes #53006

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 2ee930cc6e37..9f47d6f88b4f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -43100,6 +43100,15 @@ static SDValue combineSelectOfTwoConstants(SDNode *N, SelectionDAG &DAG) {
   // multiplier, convert to 'and' + 'add'.
   const APInt &TrueVal = TrueC->getAPIntValue();
   const APInt &FalseVal = FalseC->getAPIntValue();
+
+  // We have a more efficient lowering for "(X == 0) ? Y : -1" using SBB.
+  if ((TrueVal.isAllOnes() || FalseVal.isAllOnes()) &&
+      Cond.getOpcode() == ISD::SETCC && isNullConstant(Cond.getOperand(1))) {
+    ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
+    if (CC == ISD::SETEQ || CC == ISD::SETNE)
+      return SDValue();
+  }
+
   bool OV;
   APInt Diff = TrueVal.ssub_ov(FalseVal, OV);
   if (OV)

diff  --git a/llvm/test/CodeGen/X86/select.ll b/llvm/test/CodeGen/X86/select.ll
index 404390c80b53..81229e301d65 100644
--- a/llvm/test/CodeGen/X86/select.ll
+++ b/llvm/test/CodeGen/X86/select.ll
@@ -770,13 +770,21 @@ define i64 @test9b(i64 %x, i64 %y) nounwind readnone ssp noredzone {
 
 ;; Select between -1 and 1.
 define i64 @test10(i64 %x, i64 %y) nounwind readnone ssp noredzone {
-; CHECK-LABEL: test10:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    testq %rdi, %rdi
-; CHECK-NEXT:    setne %al
-; CHECK-NEXT:    leaq -1(%rax,%rax), %rax
-; CHECK-NEXT:    retq
+; GENERIC-LABEL: test10:
+; GENERIC:       ## %bb.0:
+; GENERIC-NEXT:    cmpq $1, %rdi
+; GENERIC-NEXT:    sbbq %rax, %rax
+; GENERIC-NEXT:    orq $1, %rax
+; GENERIC-NEXT:    retq
+;
+; ATOM-LABEL: test10:
+; ATOM:       ## %bb.0:
+; ATOM-NEXT:    cmpq $1, %rdi
+; ATOM-NEXT:    sbbq %rax, %rax
+; ATOM-NEXT:    orq $1, %rax
+; ATOM-NEXT:    nop
+; ATOM-NEXT:    nop
+; ATOM-NEXT:    retq
 ;
 ; ATHLON-LABEL: test10:
 ; ATHLON:       ## %bb.0:
@@ -1054,28 +1062,35 @@ define i8 @nezero_all_ones_or_const(i8 %x) {
 }
 
 define i32 @PR53006(i32 %x) {
-; CHECK-LABEL: PR53006:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    testl %edi, %edi
-; CHECK-NEXT:    sete %al
-; CHECK-NEXT:    leal -1(%rax,%rax), %eax
-; CHECK-NEXT:    retq
+; GENERIC-LABEL: PR53006:
+; GENERIC:       ## %bb.0:
+; GENERIC-NEXT:    negl %edi
+; GENERIC-NEXT:    sbbl %eax, %eax
+; GENERIC-NEXT:    orl $1, %eax
+; GENERIC-NEXT:    retq
+;
+; ATOM-LABEL: PR53006:
+; ATOM:       ## %bb.0:
+; ATOM-NEXT:    negl %edi
+; ATOM-NEXT:    sbbl %eax, %eax
+; ATOM-NEXT:    orl $1, %eax
+; ATOM-NEXT:    nop
+; ATOM-NEXT:    nop
+; ATOM-NEXT:    retq
 ;
 ; ATHLON-LABEL: PR53006:
 ; ATHLON:       ## %bb.0:
 ; ATHLON-NEXT:    xorl %eax, %eax
-; ATHLON-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
-; ATHLON-NEXT:    sete %al
-; ATHLON-NEXT:    leal -1(%eax,%eax), %eax
+; ATHLON-NEXT:    cmpl {{[0-9]+}}(%esp), %eax
+; ATHLON-NEXT:    sbbl %eax, %eax
+; ATHLON-NEXT:    orl $1, %eax
 ; ATHLON-NEXT:    retl
 ;
 ; MCU-LABEL: PR53006:
 ; MCU:       # %bb.0:
-; MCU-NEXT:    xorl %ecx, %ecx
-; MCU-NEXT:    testl %eax, %eax
-; MCU-NEXT:    sete %cl
-; MCU-NEXT:    leal -1(%ecx,%ecx), %eax
+; MCU-NEXT:    negl %eax
+; MCU-NEXT:    sbbl %eax, %eax
+; MCU-NEXT:    orl $1, %eax
 ; MCU-NEXT:    retl
   %z = icmp eq i32 %x, 0
   %r = select i1 %z, i32 1, i32 -1


        


More information about the llvm-commits mailing list