[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