[llvm] add17fc - [RISCV] Combine (select_cc (srl (and X, 1<<C), C), 0, eq/ne, true, fale)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 20 22:32:18 PDT 2022


Author: Craig Topper
Date: 2022-07-20T22:32:11-07:00
New Revision: add17fc8e4ceb78fb7eafac49d519001c168bd7a

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

LOG: [RISCV] Combine (select_cc (srl (and X, 1<<C), C), 0, eq/ne, true, fale)

(srl (and X, 1<<C), C) is the form we receive for testing bit C.
An earlier combine removed the setcc so it wasn't there to match
when we created the SELECT_CC. This doesn't happen for BR_CC because
generic DAG combine rebuilds the setcc if it is used by BRCOND.

We can shift X left by XLen-1-C to put the bit to be tested in the
MSB, and use a signed compare with 0 to test the MSB.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/bittest.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d1274894f63b..66cfbe2feda3 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8745,6 +8745,29 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
     return true;
   }
 
+  // Fold ((srl (and X, 1<<C), C), 0, eq/ne) -> ((shl X, XLen-1-C), 0, ge/lt)
+  if (isNullConstant(RHS) && LHS.getOpcode() == ISD::SRL && LHS.hasOneUse() &&
+      LHS.getOperand(1).getOpcode() == ISD::Constant) {
+    SDValue LHS0 = LHS.getOperand(0);
+    if (LHS0.getOpcode() == ISD::AND &&
+        LHS0.getOperand(1).getOpcode() == ISD::Constant) {
+      uint64_t Mask = LHS0.getConstantOperandVal(1);
+      uint64_t ShAmt = LHS.getConstantOperandVal(1);
+      if (isPowerOf2_64(Mask) && Log2_64(Mask) == ShAmt) {
+        CCVal = CCVal == ISD::SETEQ ? ISD::SETGE : ISD::SETLT;
+        CC = DAG.getCondCode(CCVal);
+
+        ShAmt = LHS.getValueSizeInBits() - 1 - ShAmt;
+        LHS = LHS0.getOperand(0);
+        if (ShAmt != 0)
+          LHS =
+              DAG.getNode(ISD::SHL, DL, LHS.getValueType(), LHS0.getOperand(0),
+                          DAG.getConstant(ShAmt, DL, LHS.getValueType()));
+        return true;
+      }
+    }
+  }
+
   // (X, 1, setne) -> // (X, 0, seteq) if we can prove X is 0/1.
   // This can occur when legalizing some floating point comparisons.
   APInt Mask = APInt::getBitsSetFrom(LHS.getValueSizeInBits(), 1);

diff  --git a/llvm/test/CodeGen/RISCV/bittest.ll b/llvm/test/CodeGen/RISCV/bittest.ll
index b02c94f075da..5d2fcb328bf8 100644
--- a/llvm/test/CodeGen/RISCV/bittest.ll
+++ b/llvm/test/CodeGen/RISCV/bittest.ll
@@ -454,37 +454,25 @@ define signext i32 @bit_10_z_select_i32(i32 signext %a, i32 signext %b, i32 sign
 }
 
 define signext i32 @bit_10_nz_select_i32(i32 signext %a, i32 signext %b, i32 signext %c) {
-; RV32I-LABEL: bit_10_nz_select_i32:
-; RV32I:       # %bb.0:
-; RV32I-NEXT:    slli a0, a0, 21
-; RV32I-NEXT:    srli a3, a0, 31
-; RV32I-NEXT:    mv a0, a1
-; RV32I-NEXT:    bnez a3, .LBB16_2
-; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    mv a0, a2
-; RV32I-NEXT:  .LBB16_2:
-; RV32I-NEXT:    ret
-;
-; RV64I-LABEL: bit_10_nz_select_i32:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 53
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB16_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB16_2:
-; RV64I-NEXT:    ret
+; RV32-LABEL: bit_10_nz_select_i32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a3, a0, 21
+; RV32-NEXT:    mv a0, a1
+; RV32-NEXT:    bltz a3, .LBB16_2
+; RV32-NEXT:  # %bb.1:
+; RV32-NEXT:    mv a0, a2
+; RV32-NEXT:  .LBB16_2:
+; RV32-NEXT:    ret
 ;
-; ZBS-LABEL: bit_10_nz_select_i32:
-; ZBS:       # %bb.0:
-; ZBS-NEXT:    bexti a3, a0, 10
-; ZBS-NEXT:    mv a0, a1
-; ZBS-NEXT:    bnez a3, .LBB16_2
-; ZBS-NEXT:  # %bb.1:
-; ZBS-NEXT:    mv a0, a2
-; ZBS-NEXT:  .LBB16_2:
-; ZBS-NEXT:    ret
+; RV64-LABEL: bit_10_nz_select_i32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 53
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB16_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB16_2:
+; RV64-NEXT:    ret
   %1 = and i32 %a, 1024
   %2 = icmp ne i32 %1, 0
   %3 = select i1 %2, i32 %b, i32 %c
@@ -518,37 +506,25 @@ define signext i32 @bit_11_z_select_i32(i32 signext %a, i32 signext %b, i32 sign
 }
 
 define signext i32 @bit_11_nz_select_i32(i32 signext %a, i32 signext %b, i32 signext %c) {
-; RV32I-LABEL: bit_11_nz_select_i32:
-; RV32I:       # %bb.0:
-; RV32I-NEXT:    slli a0, a0, 20
-; RV32I-NEXT:    srli a3, a0, 31
-; RV32I-NEXT:    mv a0, a1
-; RV32I-NEXT:    bnez a3, .LBB18_2
-; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    mv a0, a2
-; RV32I-NEXT:  .LBB18_2:
-; RV32I-NEXT:    ret
-;
-; RV64I-LABEL: bit_11_nz_select_i32:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 52
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB18_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB18_2:
-; RV64I-NEXT:    ret
+; RV32-LABEL: bit_11_nz_select_i32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a3, a0, 20
+; RV32-NEXT:    mv a0, a1
+; RV32-NEXT:    bltz a3, .LBB18_2
+; RV32-NEXT:  # %bb.1:
+; RV32-NEXT:    mv a0, a2
+; RV32-NEXT:  .LBB18_2:
+; RV32-NEXT:    ret
 ;
-; ZBS-LABEL: bit_11_nz_select_i32:
-; ZBS:       # %bb.0:
-; ZBS-NEXT:    bexti a3, a0, 11
-; ZBS-NEXT:    mv a0, a1
-; ZBS-NEXT:    bnez a3, .LBB18_2
-; ZBS-NEXT:  # %bb.1:
-; ZBS-NEXT:    mv a0, a2
-; ZBS-NEXT:  .LBB18_2:
-; ZBS-NEXT:    ret
+; RV64-LABEL: bit_11_nz_select_i32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 52
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB18_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB18_2:
+; RV64-NEXT:    ret
   %1 = and i32 %a, 2048
   %2 = icmp ne i32 %1, 0
   %3 = select i1 %2, i32 %b, i32 %c
@@ -582,37 +558,25 @@ define signext i32 @bit_20_z_select_i32(i32 signext %a, i32 signext %b, i32 sign
 }
 
 define signext i32 @bit_20_nz_select_i32(i32 signext %a, i32 signext %b, i32 signext %c) {
-; RV32I-LABEL: bit_20_nz_select_i32:
-; RV32I:       # %bb.0:
-; RV32I-NEXT:    slli a0, a0, 11
-; RV32I-NEXT:    srli a3, a0, 31
-; RV32I-NEXT:    mv a0, a1
-; RV32I-NEXT:    bnez a3, .LBB20_2
-; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    mv a0, a2
-; RV32I-NEXT:  .LBB20_2:
-; RV32I-NEXT:    ret
-;
-; RV64I-LABEL: bit_20_nz_select_i32:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 43
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB20_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB20_2:
-; RV64I-NEXT:    ret
+; RV32-LABEL: bit_20_nz_select_i32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a3, a0, 11
+; RV32-NEXT:    mv a0, a1
+; RV32-NEXT:    bltz a3, .LBB20_2
+; RV32-NEXT:  # %bb.1:
+; RV32-NEXT:    mv a0, a2
+; RV32-NEXT:  .LBB20_2:
+; RV32-NEXT:    ret
 ;
-; ZBS-LABEL: bit_20_nz_select_i32:
-; ZBS:       # %bb.0:
-; ZBS-NEXT:    bexti a3, a0, 20
-; ZBS-NEXT:    mv a0, a1
-; ZBS-NEXT:    bnez a3, .LBB20_2
-; ZBS-NEXT:  # %bb.1:
-; ZBS-NEXT:    mv a0, a2
-; ZBS-NEXT:  .LBB20_2:
-; ZBS-NEXT:    ret
+; RV64-LABEL: bit_20_nz_select_i32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 43
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB20_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB20_2:
+; RV64-NEXT:    ret
   %1 = and i32 %a, 1048576
   %2 = icmp ne i32 %1, 0
   %3 = select i1 %2, i32 %b, i32 %c
@@ -714,16 +678,15 @@ define i64 @bit_10_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32I-NEXT:  .LBB24_2:
 ; RV32I-NEXT:    ret
 ;
-; RV64I-LABEL: bit_10_nz_select_i64:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 53
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB24_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB24_2:
-; RV64I-NEXT:    ret
+; RV64-LABEL: bit_10_nz_select_i64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 53
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB24_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB24_2:
+; RV64-NEXT:    ret
 ;
 ; RV32ZBS-LABEL: bit_10_nz_select_i64:
 ; RV32ZBS:       # %bb.0:
@@ -736,16 +699,6 @@ define i64 @bit_10_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32ZBS-NEXT:    mv a1, a5
 ; RV32ZBS-NEXT:  .LBB24_2:
 ; RV32ZBS-NEXT:    ret
-;
-; RV64ZBS-LABEL: bit_10_nz_select_i64:
-; RV64ZBS:       # %bb.0:
-; RV64ZBS-NEXT:    bexti a3, a0, 10
-; RV64ZBS-NEXT:    mv a0, a1
-; RV64ZBS-NEXT:    bnez a3, .LBB24_2
-; RV64ZBS-NEXT:  # %bb.1:
-; RV64ZBS-NEXT:    mv a0, a2
-; RV64ZBS-NEXT:  .LBB24_2:
-; RV64ZBS-NEXT:    ret
   %1 = and i64 %a, 1024
   %2 = icmp ne i64 %1, 0
   %3 = select i1 %2, i64 %b, i64 %c
@@ -794,16 +747,15 @@ define i64 @bit_11_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32I-NEXT:  .LBB26_2:
 ; RV32I-NEXT:    ret
 ;
-; RV64I-LABEL: bit_11_nz_select_i64:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 52
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB26_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB26_2:
-; RV64I-NEXT:    ret
+; RV64-LABEL: bit_11_nz_select_i64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 52
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB26_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB26_2:
+; RV64-NEXT:    ret
 ;
 ; RV32ZBS-LABEL: bit_11_nz_select_i64:
 ; RV32ZBS:       # %bb.0:
@@ -816,16 +768,6 @@ define i64 @bit_11_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32ZBS-NEXT:    mv a1, a5
 ; RV32ZBS-NEXT:  .LBB26_2:
 ; RV32ZBS-NEXT:    ret
-;
-; RV64ZBS-LABEL: bit_11_nz_select_i64:
-; RV64ZBS:       # %bb.0:
-; RV64ZBS-NEXT:    bexti a3, a0, 11
-; RV64ZBS-NEXT:    mv a0, a1
-; RV64ZBS-NEXT:    bnez a3, .LBB26_2
-; RV64ZBS-NEXT:  # %bb.1:
-; RV64ZBS-NEXT:    mv a0, a2
-; RV64ZBS-NEXT:  .LBB26_2:
-; RV64ZBS-NEXT:    ret
   %1 = and i64 %a, 2048
   %2 = icmp ne i64 %1, 0
   %3 = select i1 %2, i64 %b, i64 %c
@@ -874,16 +816,15 @@ define i64 @bit_20_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32I-NEXT:  .LBB28_2:
 ; RV32I-NEXT:    ret
 ;
-; RV64I-LABEL: bit_20_nz_select_i64:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 43
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB28_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB28_2:
-; RV64I-NEXT:    ret
+; RV64-LABEL: bit_20_nz_select_i64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 43
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB28_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB28_2:
+; RV64-NEXT:    ret
 ;
 ; RV32ZBS-LABEL: bit_20_nz_select_i64:
 ; RV32ZBS:       # %bb.0:
@@ -896,16 +837,6 @@ define i64 @bit_20_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32ZBS-NEXT:    mv a1, a5
 ; RV32ZBS-NEXT:  .LBB28_2:
 ; RV32ZBS-NEXT:    ret
-;
-; RV64ZBS-LABEL: bit_20_nz_select_i64:
-; RV64ZBS:       # %bb.0:
-; RV64ZBS-NEXT:    bexti a3, a0, 20
-; RV64ZBS-NEXT:    mv a0, a1
-; RV64ZBS-NEXT:    bnez a3, .LBB28_2
-; RV64ZBS-NEXT:  # %bb.1:
-; RV64ZBS-NEXT:    mv a0, a2
-; RV64ZBS-NEXT:  .LBB28_2:
-; RV64ZBS-NEXT:    ret
   %1 = and i64 %a, 1048576
   %2 = icmp ne i64 %1, 0
   %3 = select i1 %2, i64 %b, i64 %c
@@ -954,9 +885,9 @@ define i64 @bit_31_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ;
 ; RV64-LABEL: bit_31_nz_select_i64:
 ; RV64:       # %bb.0:
-; RV64-NEXT:    srliw a3, a0, 31
+; RV64-NEXT:    slli a3, a0, 32
 ; RV64-NEXT:    mv a0, a1
-; RV64-NEXT:    bnez a3, .LBB30_2
+; RV64-NEXT:    bltz a3, .LBB30_2
 ; RV64-NEXT:  # %bb.1:
 ; RV64-NEXT:    mv a0, a2
 ; RV64-NEXT:  .LBB30_2:
@@ -1008,26 +939,15 @@ define i64 @bit_32_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32-NEXT:  .LBB32_2:
 ; RV32-NEXT:    ret
 ;
-; RV64I-LABEL: bit_32_nz_select_i64:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 31
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB32_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB32_2:
-; RV64I-NEXT:    ret
-;
-; RV64ZBS-LABEL: bit_32_nz_select_i64:
-; RV64ZBS:       # %bb.0:
-; RV64ZBS-NEXT:    bexti a3, a0, 32
-; RV64ZBS-NEXT:    mv a0, a1
-; RV64ZBS-NEXT:    bnez a3, .LBB32_2
-; RV64ZBS-NEXT:  # %bb.1:
-; RV64ZBS-NEXT:    mv a0, a2
-; RV64ZBS-NEXT:  .LBB32_2:
-; RV64ZBS-NEXT:    ret
+; RV64-LABEL: bit_32_nz_select_i64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 31
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB32_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB32_2:
+; RV64-NEXT:    ret
   %1 = and i64 %a, 4294967296
   %2 = icmp ne i64 %1, 0
   %3 = select i1 %2, i64 %b, i64 %c
@@ -1076,16 +996,15 @@ define i64 @bit_55_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32I-NEXT:  .LBB34_2:
 ; RV32I-NEXT:    ret
 ;
-; RV64I-LABEL: bit_55_nz_select_i64:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 8
-; RV64I-NEXT:    srli a3, a0, 63
-; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    bnez a3, .LBB34_2
-; RV64I-NEXT:  # %bb.1:
-; RV64I-NEXT:    mv a0, a2
-; RV64I-NEXT:  .LBB34_2:
-; RV64I-NEXT:    ret
+; RV64-LABEL: bit_55_nz_select_i64:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a3, a0, 8
+; RV64-NEXT:    mv a0, a1
+; RV64-NEXT:    bltz a3, .LBB34_2
+; RV64-NEXT:  # %bb.1:
+; RV64-NEXT:    mv a0, a2
+; RV64-NEXT:  .LBB34_2:
+; RV64-NEXT:    ret
 ;
 ; RV32ZBS-LABEL: bit_55_nz_select_i64:
 ; RV32ZBS:       # %bb.0:
@@ -1098,16 +1017,6 @@ define i64 @bit_55_nz_select_i64(i64 %a, i64 %b, i64 %c) {
 ; RV32ZBS-NEXT:    mv a1, a5
 ; RV32ZBS-NEXT:  .LBB34_2:
 ; RV32ZBS-NEXT:    ret
-;
-; RV64ZBS-LABEL: bit_55_nz_select_i64:
-; RV64ZBS:       # %bb.0:
-; RV64ZBS-NEXT:    bexti a3, a0, 55
-; RV64ZBS-NEXT:    mv a0, a1
-; RV64ZBS-NEXT:    bnez a3, .LBB34_2
-; RV64ZBS-NEXT:  # %bb.1:
-; RV64ZBS-NEXT:    mv a0, a2
-; RV64ZBS-NEXT:  .LBB34_2:
-; RV64ZBS-NEXT:    ret
   %1 = and i64 %a, 36028797018963968
   %2 = icmp ne i64 %1, 0
   %3 = select i1 %2, i64 %b, i64 %c


        


More information about the llvm-commits mailing list