[llvm] 9bceb89 - [X86] (0 - SetCC) | C -> (zext (not SetCC)) * (C + 1) - 1 if we can get a LEA out of it.

Amaury Séchet via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 10 08:12:06 PDT 2022


Author: Amaury Séchet
Date: 2022-08-10T15:12:00Z
New Revision: 9bceb8981d32fe9465257c31413395f445ab05d8

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

LOG: [X86] (0 - SetCC) | C -> (zext (not SetCC)) * (C + 1) - 1 if we can get a LEA out of it.

This adresses various regression in D131260 , as well as is a useful optimization in itself.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D131358

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/or-lea.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1d5592e7536f..00f42c210a73 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -48489,6 +48489,31 @@ static SDValue combineOr(SDNode *N, SelectionDAG &DAG,
   if (SDValue R = combineLogicBlendIntoPBLENDV(N, DAG, Subtarget))
     return R;
 
+  // (0 - SetCC) | C -> (zext (not SetCC)) * (C + 1) - 1 if we can get a LEA out of it.
+  if ((VT == MVT::i32 || VT == MVT::i64) &&
+      N0.getOpcode() == ISD::SUB && N0.hasOneUse() &&
+      isNullConstant(N0.getOperand(0))) {
+    SDValue Cond = N0.getOperand(1);
+    if (Cond.getOpcode() == ISD::ZERO_EXTEND && Cond.hasOneUse())
+      Cond = Cond.getOperand(0);
+
+    if (Cond.getOpcode() == X86ISD::SETCC && Cond.hasOneUse()) {
+      if (auto *CN = dyn_cast<ConstantSDNode>(N1)) {
+        unsigned Val = CN->getZExtValue();
+        if (Val == 1 || Val == 2 || Val == 3 || Val == 4 || Val == 7 || Val == 8) {
+          X86::CondCode CCode = (X86::CondCode)Cond.getConstantOperandVal(0);
+          CCode = X86::GetOppositeBranchCondition(CCode);
+          SDValue NotCond = getSETCC(CCode, Cond.getOperand(1), SDLoc(Cond), DAG);
+
+          SDValue R = DAG.getZExtOrTrunc(NotCond, dl, VT);
+          R = DAG.getNode(ISD::MUL, dl, VT, R, DAG.getConstant(Val + 1, dl, VT));
+          R = DAG.getNode(ISD::SUB, dl, VT, R, DAG.getConstant(1, dl, VT));
+          return R;
+        }
+      }
+    }
+  }
+
   // Combine OR(X,KSHIFTL(Y,Elts/2)) -> CONCAT_VECTORS(X,Y) == KUNPCK(X,Y).
   // Combine OR(KSHIFTL(X,Elts/2),Y) -> CONCAT_VECTORS(Y,X) == KUNPCK(Y,X).
   // iff the upper elements of the non-shifted arg are zero.

diff  --git a/llvm/test/CodeGen/X86/or-lea.ll b/llvm/test/CodeGen/X86/or-lea.ll
index b0bbd9a24e6d..bf44ab8fccfe 100644
--- a/llvm/test/CodeGen/X86/or-lea.ll
+++ b/llvm/test/CodeGen/X86/or-lea.ll
@@ -504,18 +504,16 @@ define i32 @or_sext1(i32 %x) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    xorl %eax, %eax
 ; X86-NEXT:    cmpl $43, {{[0-9]+}}(%esp)
-; X86-NEXT:    setge %al
-; X86-NEXT:    negl %eax
-; X86-NEXT:    orl $1, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    leal -1(%eax,%eax), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: or_sext1:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpl $43, %edi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negl %eax
-; X64-NEXT:    orl $1, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leal -1(%rax,%rax), %eax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i32 %x, 42
   %sext = sext i1 %cmp to i32
@@ -541,9 +539,8 @@ define i64 @or_sext1_64(i64 %x) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpq $43, %rdi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negq %rax
-; X64-NEXT:    orq $1, %rax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leaq -1(%rax,%rax), %rax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i64 %x, 42
   %sext = sext i1 %cmp to i64
@@ -556,18 +553,16 @@ define i32 @or_sext2(i32 %x) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    xorl %eax, %eax
 ; X86-NEXT:    cmpl $43, {{[0-9]+}}(%esp)
-; X86-NEXT:    setge %al
-; X86-NEXT:    negl %eax
-; X86-NEXT:    orl $2, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    leal -1(%eax,%eax,2), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: or_sext2:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpl $43, %edi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negl %eax
-; X64-NEXT:    orl $2, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leal -1(%rax,%rax,2), %eax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i32 %x, 42
   %sext = sext i1 %cmp to i32
@@ -593,9 +588,8 @@ define i64 @or_sext2_64(i64 %x) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpq $43, %rdi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negq %rax
-; X64-NEXT:    orq $2, %rax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leaq -1(%rax,%rax,2), %rax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i64 %x, 42
   %sext = sext i1 %cmp to i64
@@ -608,18 +602,16 @@ define i32 @or_sext3(i32 %x) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    xorl %eax, %eax
 ; X86-NEXT:    cmpl $43, {{[0-9]+}}(%esp)
-; X86-NEXT:    setge %al
-; X86-NEXT:    negl %eax
-; X86-NEXT:    orl $3, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    leal -1(,%eax,4), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: or_sext3:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpl $43, %edi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negl %eax
-; X64-NEXT:    orl $3, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leal -1(,%rax,4), %eax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i32 %x, 42
   %sext = sext i1 %cmp to i32
@@ -645,9 +637,8 @@ define i64 @or_sext3_64(i64 %x) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpq $43, %rdi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negq %rax
-; X64-NEXT:    orq $3, %rax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leaq -1(,%rax,4), %rax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i64 %x, 42
   %sext = sext i1 %cmp to i64
@@ -660,18 +651,16 @@ define i32 @or_sext4(i32 %x) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    xorl %eax, %eax
 ; X86-NEXT:    cmpl $43, {{[0-9]+}}(%esp)
-; X86-NEXT:    setge %al
-; X86-NEXT:    negl %eax
-; X86-NEXT:    orl $4, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    leal -1(%eax,%eax,4), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: or_sext4:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpl $43, %edi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negl %eax
-; X64-NEXT:    orl $4, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leal -1(%rax,%rax,4), %eax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i32 %x, 42
   %sext = sext i1 %cmp to i32
@@ -697,9 +686,8 @@ define i64 @or_sext4_64(i64 %x) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpq $43, %rdi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negq %rax
-; X64-NEXT:    orq $4, %rax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leaq -1(%rax,%rax,4), %rax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i64 %x, 42
   %sext = sext i1 %cmp to i64
@@ -712,18 +700,16 @@ define i32 @or_sext7(i32 %x) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    xorl %eax, %eax
 ; X86-NEXT:    cmpl $43, {{[0-9]+}}(%esp)
-; X86-NEXT:    setge %al
-; X86-NEXT:    negl %eax
-; X86-NEXT:    orl $7, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    leal -1(,%eax,8), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: or_sext7:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpl $43, %edi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negl %eax
-; X64-NEXT:    orl $7, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leal -1(,%rax,8), %eax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i32 %x, 42
   %sext = sext i1 %cmp to i32
@@ -749,9 +735,8 @@ define i64 @or_sext7_64(i64 %x) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpq $43, %rdi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negq %rax
-; X64-NEXT:    orq $7, %rax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leaq -1(,%rax,8), %rax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i64 %x, 42
   %sext = sext i1 %cmp to i64
@@ -764,18 +749,16 @@ define i32 @or_sext8(i32 %x) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    xorl %eax, %eax
 ; X86-NEXT:    cmpl $43, {{[0-9]+}}(%esp)
-; X86-NEXT:    setge %al
-; X86-NEXT:    negl %eax
-; X86-NEXT:    orl $8, %eax
+; X86-NEXT:    setl %al
+; X86-NEXT:    leal -1(%eax,%eax,8), %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: or_sext8:
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpl $43, %edi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negl %eax
-; X64-NEXT:    orl $8, %eax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leal -1(%rax,%rax,8), %eax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i32 %x, 42
   %sext = sext i1 %cmp to i32
@@ -801,9 +784,8 @@ define i64 @or_sext8_64(i64 %x) {
 ; X64:       # %bb.0:
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    cmpq $43, %rdi
-; X64-NEXT:    setge %al
-; X64-NEXT:    negq %rax
-; X64-NEXT:    orq $8, %rax
+; X64-NEXT:    setl %al
+; X64-NEXT:    leaq -1(%rax,%rax,8), %rax
 ; X64-NEXT:    retq
   %cmp = icmp sgt i64 %x, 42
   %sext = sext i1 %cmp to i64


        


More information about the llvm-commits mailing list