[llvm] [DAG] Convert select of constants to arithmetic operations (PR #198951)
dong jianqiang via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 00:36:50 PDT 2026
https://github.com/dongjianqiang2 updated https://github.com/llvm/llvm-project/pull/198951
>From 05fac248423e93d54c231717bd4810473d2730df Mon Sep 17 00:00:00 2001
From: Dong JianQiang <dongjianqiang2 at huawei.com>
Date: Fri, 29 May 2026 02:53:00 +0800
Subject: [PATCH 1/5] [DAG] Add missing select Cond, 0, Pow2 fold in
foldSelectOfConstants
Add the missing swapped case as an unconditional fold:
select Cond, 0, Pow2 --> (zext (!Cond)) << log2(Pow2)
This is unconditional like the existing 0/1, 1/0, 0/-1, -1/0 folds, so
it fires for all targets without requiring a target hook. Targets that
prefer the original form can add a backend combine to reverse it.
Fixes #196488
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 9 +++
llvm/test/CodeGen/AArch64/arm64-csel.ll | 5 +-
llvm/test/CodeGen/AArch64/bfis-in-loop.ll | 60 +++++++++----------
llvm/test/CodeGen/AArch64/select_cc.ll | 8 +--
llvm/test/CodeGen/AArch64/select_const.ll | 5 +-
llvm/test/CodeGen/AMDGPU/sdiv64.ll | 11 ++--
llvm/test/CodeGen/AMDGPU/srem64.ll | 11 ++--
llvm/test/CodeGen/AMDGPU/udiv64.ll | 11 ++--
llvm/test/CodeGen/AMDGPU/urem64.ll | 11 ++--
.../CodeGen/PowerPC/fp-strict-conv-f128.ll | 16 ++---
llvm/test/CodeGen/PowerPC/nofpexcept.ll | 9 +--
.../ppcf128-constrained-fp-intrinsics.ll | 13 ++--
llvm/test/CodeGen/PowerPC/pr49509.ll | 12 ++--
llvm/test/CodeGen/PowerPC/select_const.ll | 20 ++-----
llvm/test/CodeGen/RISCV/select-zbb.ll | 32 +++++-----
llvm/test/CodeGen/Thumb/branchless-cmp.ll | 18 +++---
16 files changed, 120 insertions(+), 131 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 51f730491207b..81fada8bebbac 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12766,6 +12766,15 @@ SDValue DAGCombiner::foldSelectOfConstants(SDNode *N) {
return NotCond;
}
+ // select Cond, 0, Pow2 --> (zext (!Cond)) << log2(Pow2)
+ if (C1->isZero() && C2->getAPIntValue().isPowerOf2()) {
+ SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1);
+ NotCond = DAG.getZExtOrTrunc(NotCond, DL, VT);
+ SDValue ShAmtC =
+ DAG.getShiftAmountConstant(C2->getAPIntValue().exactLogBase2(), VT, DL);
+ return DAG.getNode(ISD::SHL, DL, VT, NotCond, ShAmtC);
+ }
+
// Use a target hook because some targets may prefer to transform in the
// other direction.
if (!shouldConvertSelectOfConstantsToMath(Cond, VT, TLI))
diff --git a/llvm/test/CodeGen/AArch64/arm64-csel.ll b/llvm/test/CodeGen/AArch64/arm64-csel.ll
index f677f2f77fc61..be902e0db1d38 100644
--- a/llvm/test/CodeGen/AArch64/arm64-csel.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-csel.ll
@@ -387,9 +387,8 @@ entry:
define i64 @foo18_overflow4(i1 %cmp) nounwind readnone optsize ssp {
; CHECK-SD-LABEL: foo18_overflow4:
; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mov x8, #-9223372036854775808 // =0x8000000000000000
-; CHECK-SD-NEXT: tst w0, #0x1
-; CHECK-SD-NEXT: csel x0, xzr, x8, ne
+; CHECK-SD-NEXT: mvn w8, w0
+; CHECK-SD-NEXT: lsl x0, x8, #63
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: foo18_overflow4:
diff --git a/llvm/test/CodeGen/AArch64/bfis-in-loop.ll b/llvm/test/CodeGen/AArch64/bfis-in-loop.ll
index 43d49da1abd21..8b8e653b4249c 100644
--- a/llvm/test/CodeGen/AArch64/bfis-in-loop.ll
+++ b/llvm/test/CodeGen/AArch64/bfis-in-loop.ll
@@ -13,26 +13,25 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
define i64 @bfis_in_loop_zero() {
; CHECK-LABEL: bfis_in_loop_zero:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: adrp x9, :got:global
+; CHECK-NEXT: adrp x8, :got:global
; CHECK-NEXT: mov x0, xzr
-; CHECK-NEXT: mov w8, wzr
-; CHECK-NEXT: ldr x9, [x9, :got_lo12:global]
-; CHECK-NEXT: mov w10, #65536 // =0x10000
-; CHECK-NEXT: ldr x9, [x9]
+; CHECK-NEXT: mov w9, wzr
+; CHECK-NEXT: ldr x8, [x8, :got_lo12:global]
+; CHECK-NEXT: ldr x8, [x8]
; CHECK-NEXT: .LBB0_1: // %midblock
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrh w11, [x9, #72]
-; CHECK-NEXT: and x13, x0, #0xffffffff00000000
-; CHECK-NEXT: lsr w12, w11, #8
-; CHECK-NEXT: cmp w11, #0
-; CHECK-NEXT: csel w8, w8, w12, eq
-; CHECK-NEXT: ldr x12, [x9, #8]
-; CHECK-NEXT: csel x9, xzr, x10, eq
-; CHECK-NEXT: bfi w11, w8, #8, #24
-; CHECK-NEXT: orr x13, x9, x13
-; CHECK-NEXT: ldr x9, [x12, #16]
-; CHECK-NEXT: orr x0, x13, x11
-; CHECK-NEXT: cbnz x12, .LBB0_1
+; CHECK-NEXT: ldrh w10, [x8, #72]
+; CHECK-NEXT: ldr x13, [x8, #8]
+; CHECK-NEXT: lsr w11, w10, #8
+; CHECK-NEXT: cmp w10, #0
+; CHECK-NEXT: ldr x8, [x13, #16]
+; CHECK-NEXT: cset w12, ne
+; CHECK-NEXT: csel w9, w9, w11, eq
+; CHECK-NEXT: and x11, x0, #0xffffffff00000000
+; CHECK-NEXT: bfi w10, w9, #8, #24
+; CHECK-NEXT: orr x11, x11, x12, lsl #16
+; CHECK-NEXT: orr x0, x11, x10
+; CHECK-NEXT: cbnz x13, .LBB0_1
; CHECK-NEXT: // %bb.2: // %exit
; CHECK-NEXT: ret
entry:
@@ -85,22 +84,21 @@ define i64 @bfis_in_loop_undef() {
; CHECK-NEXT: mov w8, wzr
; CHECK-NEXT: // implicit-def: $x0
; CHECK-NEXT: ldr x9, [x9, :got_lo12:global]
-; CHECK-NEXT: ldr x10, [x9]
-; CHECK-NEXT: mov w9, #65536 // =0x10000
+; CHECK-NEXT: ldr x9, [x9]
; CHECK-NEXT: .LBB1_1: // %midblock
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrh w11, [x10, #72]
-; CHECK-NEXT: and x13, x0, #0xffffffff00000000
-; CHECK-NEXT: lsr w12, w11, #8
-; CHECK-NEXT: cmp w11, #0
-; CHECK-NEXT: csel w8, w8, w12, eq
-; CHECK-NEXT: ldr x12, [x10, #8]
-; CHECK-NEXT: csel x10, xzr, x9, eq
-; CHECK-NEXT: bfi w11, w8, #8, #24
-; CHECK-NEXT: orr x13, x10, x13
-; CHECK-NEXT: ldr x10, [x12, #16]
-; CHECK-NEXT: orr x0, x13, x11
-; CHECK-NEXT: cbnz x12, .LBB1_1
+; CHECK-NEXT: ldrh w10, [x9, #72]
+; CHECK-NEXT: ldr x13, [x9, #8]
+; CHECK-NEXT: lsr w11, w10, #8
+; CHECK-NEXT: cmp w10, #0
+; CHECK-NEXT: ldr x9, [x13, #16]
+; CHECK-NEXT: cset w12, ne
+; CHECK-NEXT: csel w8, w8, w11, eq
+; CHECK-NEXT: and x11, x0, #0xffffffff00000000
+; CHECK-NEXT: bfi w10, w8, #8, #24
+; CHECK-NEXT: orr x11, x11, x12, lsl #16
+; CHECK-NEXT: orr x0, x11, x10
+; CHECK-NEXT: cbnz x13, .LBB1_1
; CHECK-NEXT: // %bb.2: // %exit
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/select_cc.ll b/llvm/test/CodeGen/AArch64/select_cc.ll
index a21307b555810..1eaf2022bcd3a 100644
--- a/llvm/test/CodeGen/AArch64/select_cc.ll
+++ b/llvm/test/CodeGen/AArch64/select_cc.ll
@@ -26,8 +26,8 @@ define i64 @select_ule_float_inverse(float %a, float %b) {
; CHECK-SD-LABEL: select_ule_float_inverse:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: fcmp s0, s1
-; CHECK-SD-NEXT: mov w8, #4 // =0x4
-; CHECK-SD-NEXT: csel x0, xzr, x8, le
+; CHECK-SD-NEXT: cset w8, gt
+; CHECK-SD-NEXT: ubfiz x0, x8, #2, #32
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: select_ule_float_inverse:
@@ -65,9 +65,9 @@ entry:
define i64 @select_ne_i32_inverse(i32 %a, i32 %b) {
; CHECK-SD-LABEL: select_ne_i32_inverse:
; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mov w8, #4 // =0x4
; CHECK-SD-NEXT: cmp w0, w1
-; CHECK-SD-NEXT: csel x0, xzr, x8, ne
+; CHECK-SD-NEXT: cset w8, eq
+; CHECK-SD-NEXT: ubfiz x0, x8, #2, #32
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: select_ne_i32_inverse:
diff --git a/llvm/test/CodeGen/AArch64/select_const.ll b/llvm/test/CodeGen/AArch64/select_const.ll
index daa9971dbcd58..b9e6b3a58b0ee 100644
--- a/llvm/test/CodeGen/AArch64/select_const.ll
+++ b/llvm/test/CodeGen/AArch64/select_const.ll
@@ -413,9 +413,8 @@ define i8 @sel_constants_mul_constant(i1 %cond) {
define i8 @sel_constants_sdiv_constant(i1 %cond) {
; CHECK-SD-LABEL: sel_constants_sdiv_constant:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: mov w8, #4 // =0x4
-; CHECK-SD-NEXT: tst w0, #0x1
-; CHECK-SD-NEXT: csel w0, wzr, w8, ne
+; CHECK-SD-NEXT: mvn w8, w0
+; CHECK-SD-NEXT: ubfiz w0, w8, #2, #1
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: sel_constants_sdiv_constant:
diff --git a/llvm/test/CodeGen/AMDGPU/sdiv64.ll b/llvm/test/CodeGen/AMDGPU/sdiv64.ll
index 68466abf31aa0..81f49cd56454f 100644
--- a/llvm/test/CodeGen/AMDGPU/sdiv64.ll
+++ b/llvm/test/CodeGen/AMDGPU/sdiv64.ll
@@ -1651,15 +1651,14 @@ define i64 @v_test_sdiv_pow2_k_num_i64(i64 %x) {
; GCN-IR-NEXT: v_min_u32_e32 v8, v2, v3
; GCN-IR-NEXT: v_add_i32_e32 v2, vcc, 0xffffffd0, v8
; GCN-IR-NEXT: v_addc_u32_e64 v3, s[6:7], 0, -1, vcc
-; GCN-IR-NEXT: v_cmp_eq_u64_e64 s[4:5], 0, v[0:1]
-; GCN-IR-NEXT: v_cmp_lt_u64_e32 vcc, 63, v[2:3]
+; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[4:5], 0, v[0:1]
+; GCN-IR-NEXT: v_cmp_gt_u64_e32 vcc, 64, v[2:3]
; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[6:7], 63, v[2:3]
-; GCN-IR-NEXT: v_mov_b32_e32 v4, 0x8000
-; GCN-IR-NEXT: s_or_b64 s[4:5], s[4:5], vcc
-; GCN-IR-NEXT: v_cndmask_b32_e64 v4, v4, 0, s[4:5]
-; GCN-IR-NEXT: s_xor_b64 s[4:5], s[4:5], -1
+; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], vcc
+; GCN-IR-NEXT: v_cndmask_b32_e64 v4, 0, 1, s[4:5]
; GCN-IR-NEXT: v_mov_b32_e32 v11, v10
; GCN-IR-NEXT: v_mov_b32_e32 v5, 0
+; GCN-IR-NEXT: v_lshlrev_b32_e32 v4, 15, v4
; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], s[6:7]
; GCN-IR-NEXT: s_and_saveexec_b64 s[6:7], s[4:5]
; GCN-IR-NEXT: s_cbranch_execz .LBB12_6
diff --git a/llvm/test/CodeGen/AMDGPU/srem64.ll b/llvm/test/CodeGen/AMDGPU/srem64.ll
index 82196b73b66e4..65ae7de5164a8 100644
--- a/llvm/test/CodeGen/AMDGPU/srem64.ll
+++ b/llvm/test/CodeGen/AMDGPU/srem64.ll
@@ -1799,14 +1799,13 @@ define i64 @v_test_srem_pow2_k_num_i64(i64 %x) {
; GCN-IR-NEXT: v_min_u32_e32 v8, v2, v3
; GCN-IR-NEXT: v_add_i32_e32 v2, vcc, 0xffffffd0, v8
; GCN-IR-NEXT: v_addc_u32_e64 v3, s[6:7], 0, -1, vcc
-; GCN-IR-NEXT: v_cmp_eq_u64_e64 s[4:5], 0, v[0:1]
-; GCN-IR-NEXT: v_cmp_lt_u64_e32 vcc, 63, v[2:3]
+; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[4:5], 0, v[0:1]
+; GCN-IR-NEXT: v_cmp_gt_u64_e32 vcc, 64, v[2:3]
; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[6:7], 63, v[2:3]
-; GCN-IR-NEXT: v_mov_b32_e32 v4, 0x8000
-; GCN-IR-NEXT: s_or_b64 s[4:5], s[4:5], vcc
-; GCN-IR-NEXT: v_cndmask_b32_e64 v4, v4, 0, s[4:5]
-; GCN-IR-NEXT: s_xor_b64 s[4:5], s[4:5], -1
+; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], vcc
+; GCN-IR-NEXT: v_cndmask_b32_e64 v4, 0, 1, s[4:5]
; GCN-IR-NEXT: v_mov_b32_e32 v5, 0
+; GCN-IR-NEXT: v_lshlrev_b32_e32 v4, 15, v4
; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], s[6:7]
; GCN-IR-NEXT: s_and_saveexec_b64 s[6:7], s[4:5]
; GCN-IR-NEXT: s_cbranch_execz .LBB12_6
diff --git a/llvm/test/CodeGen/AMDGPU/udiv64.ll b/llvm/test/CodeGen/AMDGPU/udiv64.ll
index edd84a5f09e5e..eed5ded0db893 100644
--- a/llvm/test/CodeGen/AMDGPU/udiv64.ll
+++ b/llvm/test/CodeGen/AMDGPU/udiv64.ll
@@ -1081,14 +1081,13 @@ define i64 @v_test_udiv_pow2_k_num_i64(i64 %x) {
; GCN-IR-NEXT: v_min_u32_e32 v8, v2, v3
; GCN-IR-NEXT: v_add_i32_e32 v4, vcc, 0xffffffd0, v8
; GCN-IR-NEXT: v_addc_u32_e64 v5, s[6:7], 0, -1, vcc
-; GCN-IR-NEXT: v_cmp_eq_u64_e64 s[4:5], 0, v[0:1]
-; GCN-IR-NEXT: v_cmp_lt_u64_e32 vcc, 63, v[4:5]
+; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[4:5], 0, v[0:1]
+; GCN-IR-NEXT: v_cmp_gt_u64_e32 vcc, 64, v[4:5]
; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[6:7], 63, v[4:5]
-; GCN-IR-NEXT: v_mov_b32_e32 v3, 0x8000
-; GCN-IR-NEXT: s_or_b64 s[4:5], s[4:5], vcc
-; GCN-IR-NEXT: v_cndmask_b32_e64 v3, v3, 0, s[4:5]
-; GCN-IR-NEXT: s_xor_b64 s[4:5], s[4:5], -1
+; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], vcc
+; GCN-IR-NEXT: v_cndmask_b32_e64 v3, 0, 1, s[4:5]
; GCN-IR-NEXT: v_mov_b32_e32 v2, 0
+; GCN-IR-NEXT: v_lshlrev_b32_e32 v3, 15, v3
; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], s[6:7]
; GCN-IR-NEXT: s_and_saveexec_b64 s[6:7], s[4:5]
; GCN-IR-NEXT: s_cbranch_execz .LBB9_6
diff --git a/llvm/test/CodeGen/AMDGPU/urem64.ll b/llvm/test/CodeGen/AMDGPU/urem64.ll
index 3bb489c654535..9ccb0531ef022 100644
--- a/llvm/test/CodeGen/AMDGPU/urem64.ll
+++ b/llvm/test/CodeGen/AMDGPU/urem64.ll
@@ -1217,14 +1217,13 @@ define i64 @v_test_urem_pow2_k_num_i64(i64 %x) {
; GCN-IR-NEXT: v_min_u32_e32 v8, v2, v3
; GCN-IR-NEXT: v_add_i32_e32 v2, vcc, 0xffffffd0, v8
; GCN-IR-NEXT: v_addc_u32_e64 v3, s[6:7], 0, -1, vcc
-; GCN-IR-NEXT: v_cmp_eq_u64_e64 s[4:5], 0, v[0:1]
-; GCN-IR-NEXT: v_cmp_lt_u64_e32 vcc, 63, v[2:3]
+; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[4:5], 0, v[0:1]
+; GCN-IR-NEXT: v_cmp_gt_u64_e32 vcc, 64, v[2:3]
; GCN-IR-NEXT: v_cmp_ne_u64_e64 s[6:7], 63, v[2:3]
-; GCN-IR-NEXT: v_mov_b32_e32 v4, 0x8000
-; GCN-IR-NEXT: s_or_b64 s[4:5], s[4:5], vcc
-; GCN-IR-NEXT: v_cndmask_b32_e64 v4, v4, 0, s[4:5]
-; GCN-IR-NEXT: s_xor_b64 s[4:5], s[4:5], -1
+; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], vcc
+; GCN-IR-NEXT: v_cndmask_b32_e64 v4, 0, 1, s[4:5]
; GCN-IR-NEXT: v_mov_b32_e32 v5, 0
+; GCN-IR-NEXT: v_lshlrev_b32_e32 v4, 15, v4
; GCN-IR-NEXT: s_and_b64 s[4:5], s[4:5], s[6:7]
; GCN-IR-NEXT: s_and_saveexec_b64 s[6:7], s[4:5]
; GCN-IR-NEXT: s_cbranch_execz .LBB8_6
diff --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
index 988ec6d8cc72b..74afba823b362 100644
--- a/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv-f128.ll
@@ -617,12 +617,13 @@ define zeroext i32 @ppcq_to_u32(ppc_fp128 %m) #0 {
; P8-NEXT: std r30, 112(r1) # 8-byte Folded Spill
; P8-NEXT: lfs f0, .LCPI13_0 at toc@l(r3)
; P8-NEXT: fcmpo cr1, f2, f3
-; P8-NEXT: lis r3, -32768
+; P8-NEXT: li r3, 1
; P8-NEXT: fcmpo cr0, f1, f0
; P8-NEXT: crand 4*cr5+lt, eq, 4*cr1+lt
; P8-NEXT: crandc 4*cr5+gt, lt, eq
; P8-NEXT: cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt
-; P8-NEXT: isel r30, 0, r3, 4*cr5+lt
+; P8-NEXT: isel r3, 0, r3, 4*cr5+lt
+; P8-NEXT: slwi r30, r3, 31
; P8-NEXT: bc 12, 4*cr5+lt, .LBB13_2
; P8-NEXT: # %bb.1: # %entry
; P8-NEXT: fmr f3, f0
@@ -639,7 +640,6 @@ define zeroext i32 @ppcq_to_u32(ppc_fp128 %m) #0 {
; P8-NEXT: mffprwz r3, f0
; P8-NEXT: xor r3, r3, r30
; P8-NEXT: ld r30, 112(r1) # 8-byte Folded Reload
-; P8-NEXT: clrldi r3, r3, 32
; P8-NEXT: addi r1, r1, 128
; P8-NEXT: ld r0, 16(r1)
; P8-NEXT: mtlr r0
@@ -658,12 +658,13 @@ define zeroext i32 @ppcq_to_u32(ppc_fp128 %m) #0 {
; P9-NEXT: std r0, 64(r1)
; P9-NEXT: lfs f0, .LCPI13_0 at toc@l(r3)
; P9-NEXT: fcmpo cr1, f2, f3
-; P9-NEXT: lis r3, -32768
+; P9-NEXT: li r3, 1
; P9-NEXT: fcmpo cr0, f1, f0
; P9-NEXT: crand 4*cr5+lt, eq, 4*cr1+lt
; P9-NEXT: crandc 4*cr5+gt, lt, eq
; P9-NEXT: cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt
-; P9-NEXT: isel r30, 0, r3, 4*cr5+lt
+; P9-NEXT: isel r3, 0, r3, 4*cr5+lt
+; P9-NEXT: slwi r30, r3, 31
; P9-NEXT: bc 12, 4*cr5+lt, .LBB13_2
; P9-NEXT: # %bb.1: # %entry
; P9-NEXT: fmr f3, f0
@@ -679,7 +680,6 @@ define zeroext i32 @ppcq_to_u32(ppc_fp128 %m) #0 {
; P9-NEXT: xscvdpsxws f0, f1
; P9-NEXT: mffprwz r3, f0
; P9-NEXT: xor r3, r3, r30
-; P9-NEXT: clrldi r3, r3, 32
; P9-NEXT: addi r1, r1, 48
; P9-NEXT: ld r0, 16(r1)
; P9-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
@@ -720,11 +720,11 @@ define zeroext i32 @ppcq_to_u32(ppc_fp128 %m) #0 {
; NOVSX-NEXT: mtfsf 1, f0
; NOVSX-NEXT: fctiwz f0, f1
; NOVSX-NEXT: stfiwx f0, 0, r3
-; NOVSX-NEXT: lis r3, -32768
+; NOVSX-NEXT: li r3, 1
; NOVSX-NEXT: lwz r4, 44(r1)
; NOVSX-NEXT: isel r3, 0, r3, 4*cr2+lt
+; NOVSX-NEXT: slwi r3, r3, 31
; NOVSX-NEXT: xor r3, r4, r3
-; NOVSX-NEXT: clrldi r3, r3, 32
; NOVSX-NEXT: addi r1, r1, 48
; NOVSX-NEXT: ld r0, 16(r1)
; NOVSX-NEXT: lwz r12, 8(r1)
diff --git a/llvm/test/CodeGen/PowerPC/nofpexcept.ll b/llvm/test/CodeGen/PowerPC/nofpexcept.ll
index 14c6e68fb9226..d63459880793f 100644
--- a/llvm/test/CodeGen/PowerPC/nofpexcept.ll
+++ b/llvm/test/CodeGen/PowerPC/nofpexcept.ll
@@ -120,9 +120,10 @@ define void @fptoint_nofpexcept(ppc_fp128 %p, fp128 %m, ptr %addr1, ptr %addr2)
; CHECK-NEXT: [[COPY17:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_lt
; CHECK-NEXT: [[CRANDC:%[0-9]+]]:crbitrc = CRANDC killed [[COPY17]], killed [[COPY16]]
; CHECK-NEXT: [[CROR:%[0-9]+]]:crbitrc = CROR killed [[CRANDC]], killed [[CRAND]]
- ; CHECK-NEXT: [[LIS:%[0-9]+]]:gprc_and_gprc_nor0 = LIS 32768
- ; CHECK-NEXT: [[LI:%[0-9]+]]:gprc_and_gprc_nor0 = LI 0
- ; CHECK-NEXT: [[ISEL:%[0-9]+]]:gprc = ISEL [[LI]], [[LIS]], [[CROR]]
+ ; CHECK-NEXT: [[LI:%[0-9]+]]:gprc_and_gprc_nor0 = LI 1
+ ; CHECK-NEXT: [[LI1:%[0-9]+]]:gprc_and_gprc_nor0 = LI 0
+ ; CHECK-NEXT: [[ISEL:%[0-9]+]]:gprc = ISEL [[LI1]], [[LI]], [[CROR]]
+ ; CHECK-NEXT: [[RLWINM:%[0-9]+]]:gprc = RLWINM killed [[ISEL]], 31, 0, 0
; CHECK-NEXT: BC [[CROR]], %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.entry:
@@ -146,7 +147,7 @@ define void @fptoint_nofpexcept(ppc_fp128 %p, fp128 %m, ptr %addr1, ptr %addr2)
; CHECK-NEXT: MTFSFb 1, [[MFFS1]], implicit-def $rm
; CHECK-NEXT: [[XSCVDPSXWS1:%[0-9]+]]:vsfrc = nofpexcept XSCVDPSXWS killed [[FADD1]], implicit $rm
; CHECK-NEXT: [[MFVSRWZ:%[0-9]+]]:gprc = MFVSRWZ killed [[XSCVDPSXWS1]]
- ; CHECK-NEXT: [[XOR:%[0-9]+]]:gprc = XOR killed [[MFVSRWZ]], killed [[ISEL]]
+ ; CHECK-NEXT: [[XOR:%[0-9]+]]:gprc = XOR killed [[MFVSRWZ]], killed [[RLWINM]]
; CHECK-NEXT: STW killed [[XOR]], 0, [[COPY1]] :: (volatile store (s32) into %ir.addr1)
; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm
entry:
diff --git a/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll b/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll
index c1ee436a40c55..bafbe9ca51366 100644
--- a/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll
+++ b/llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll
@@ -1294,12 +1294,13 @@ define i32 @test_fptoui_ppc_i32_ppc_fp128(ppc_fp128 %first) #0 {
; PC64LE-NEXT: std 0, 64(1)
; PC64LE-NEXT: lfs 0, .LCPI31_0 at toc@l(3)
; PC64LE-NEXT: fcmpo 1, 2, 3
-; PC64LE-NEXT: lis 3, -32768
+; PC64LE-NEXT: li 3, 1
; PC64LE-NEXT: fcmpo 0, 1, 0
; PC64LE-NEXT: crand 20, 2, 4
; PC64LE-NEXT: crandc 21, 0, 2
; PC64LE-NEXT: cror 20, 21, 20
-; PC64LE-NEXT: isel 30, 0, 3, 20
+; PC64LE-NEXT: isel 3, 0, 3, 20
+; PC64LE-NEXT: slwi 30, 3, 31
; PC64LE-NEXT: bc 12, 20, .LBB31_2
; PC64LE-NEXT: # %bb.1: # %entry
; PC64LE-NEXT: fmr 3, 0
@@ -1331,12 +1332,13 @@ define i32 @test_fptoui_ppc_i32_ppc_fp128(ppc_fp128 %first) #0 {
; PC64LE9-NEXT: std 0, 64(1)
; PC64LE9-NEXT: lfs 0, .LCPI31_0 at toc@l(3)
; PC64LE9-NEXT: fcmpo 1, 2, 3
-; PC64LE9-NEXT: lis 3, -32768
+; PC64LE9-NEXT: li 3, 1
; PC64LE9-NEXT: fcmpo 0, 1, 0
; PC64LE9-NEXT: crand 20, 2, 4
; PC64LE9-NEXT: crandc 21, 0, 2
; PC64LE9-NEXT: cror 20, 21, 20
-; PC64LE9-NEXT: isel 30, 0, 3, 20
+; PC64LE9-NEXT: isel 3, 0, 3, 20
+; PC64LE9-NEXT: slwi 30, 3, 31
; PC64LE9-NEXT: bc 12, 20, .LBB31_2
; PC64LE9-NEXT: # %bb.1: # %entry
; PC64LE9-NEXT: fmr 3, 0
@@ -1391,9 +1393,10 @@ define i32 @test_fptoui_ppc_i32_ppc_fp128(ppc_fp128 %first) #0 {
; PC64-NEXT: stfd 0, 120(1)
; PC64-NEXT: bc 12, 8, .LBB31_4
; PC64-NEXT: # %bb.3: # %entry
-; PC64-NEXT: lis 3, -32768
+; PC64-NEXT: li 3, 1
; PC64-NEXT: .LBB31_4: # %entry
; PC64-NEXT: lwz 4, 124(1)
+; PC64-NEXT: slwi 3, 3, 31
; PC64-NEXT: xor 3, 4, 3
; PC64-NEXT: addi 1, 1, 128
; PC64-NEXT: ld 0, 16(1)
diff --git a/llvm/test/CodeGen/PowerPC/pr49509.ll b/llvm/test/CodeGen/PowerPC/pr49509.ll
index 48fe65e48e1ff..3becda1219a1b 100644
--- a/llvm/test/CodeGen/PowerPC/pr49509.ll
+++ b/llvm/test/CodeGen/PowerPC/pr49509.ll
@@ -26,21 +26,19 @@ define void @test() {
; CHECK-NEXT: and 5, 4, 5
; CHECK-NEXT: cmpwi 3, 0
; CHECK-NEXT: li 3, 0
-; CHECK-NEXT: cmpwi 1, 5, -1
; CHECK-NEXT: li 4, 0
; CHECK-NEXT: bc 12, 2, .LBB0_5
; CHECK-NEXT: # %bb.4: # %bb66
-; CHECK-NEXT: lis 4, 256
+; CHECK-NEXT: li 4, 1
; CHECK-NEXT: .LBB0_5: # %bb66
-; CHECK-NEXT: cmpwi 5, 5, -1
+; CHECK-NEXT: cmpwi 5, -1
; CHECK-NEXT: lis 5, 512
-; CHECK-NEXT: beq 5, .LBB0_7
+; CHECK-NEXT: beq 0, .LBB0_7
; CHECK-NEXT: # %bb.6: # %bb66
-; CHECK-NEXT: mr 5, 4
+; CHECK-NEXT: slwi 5, 4, 24
; CHECK-NEXT: .LBB0_7: # %bb66
-; CHECK-NEXT: cror 20, 6, 2
-; CHECK-NEXT: stw 5, 0(3)
; CHECK-NEXT: stw 3, 0(3)
+; CHECK-NEXT: stw 5, 0(3)
; CHECK-NEXT: blr
bb:
br i1 undef, label %bb2, label %bb1
diff --git a/llvm/test/CodeGen/PowerPC/select_const.ll b/llvm/test/CodeGen/PowerPC/select_const.ll
index a48d6968aafbf..791119482489f 100644
--- a/llvm/test/CodeGen/PowerPC/select_const.ll
+++ b/llvm/test/CodeGen/PowerPC/select_const.ll
@@ -340,21 +340,11 @@ define i8 @sel_constants_mul_constant(i1 %cond) {
}
define i8 @sel_constants_sdiv_constant(i1 %cond) {
-; ISEL-LABEL: sel_constants_sdiv_constant:
-; ISEL: # %bb.0:
-; ISEL-NEXT: andi. 3, 3, 1
-; ISEL-NEXT: li 3, 4
-; ISEL-NEXT: iselgt 3, 0, 3
-; ISEL-NEXT: blr
-;
-; NO_ISEL-LABEL: sel_constants_sdiv_constant:
-; NO_ISEL: # %bb.0:
-; NO_ISEL-NEXT: andi. 3, 3, 1
-; NO_ISEL-NEXT: li 3, 0
-; NO_ISEL-NEXT: bclr 12, 1, 0
-; NO_ISEL-NEXT: # %bb.1:
-; NO_ISEL-NEXT: li 3, 4
-; NO_ISEL-NEXT: blr
+; ALL-LABEL: sel_constants_sdiv_constant:
+; ALL: # %bb.0:
+; ALL-NEXT: not 3, 3
+; ALL-NEXT: rlwinm 3, 3, 2, 29, 29
+; ALL-NEXT: blr
%sel = select i1 %cond, i8 -4, i8 23
%bo = sdiv i8 %sel, 5
ret i8 %bo
diff --git a/llvm/test/CodeGen/RISCV/select-zbb.ll b/llvm/test/CodeGen/RISCV/select-zbb.ll
index efc3f46376b4e..e8d2bf4704813 100644
--- a/llvm/test/CodeGen/RISCV/select-zbb.ll
+++ b/llvm/test/CodeGen/RISCV/select-zbb.ll
@@ -503,8 +503,8 @@ entry:
define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV32IM-LABEL: select_umax_3:
; RV32IM: # %bb.0: # %entry
-; RV32IM-NEXT: addi a0, a0, -1
-; RV32IM-NEXT: andi a2, a0, 32
+; RV32IM-NEXT: xori a2, a0, 1
+; RV32IM-NEXT: slli a2, a2, 5
; RV32IM-NEXT: mv a0, a1
; RV32IM-NEXT: bltu a2, a1, .LBB6_2
; RV32IM-NEXT: # %bb.1: # %entry
@@ -516,8 +516,8 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV64IM: # %bb.0: # %entry
; RV64IM-NEXT: mv a2, a0
; RV64IM-NEXT: sext.w a0, a1
-; RV64IM-NEXT: addi a2, a2, -1
-; RV64IM-NEXT: andi a1, a2, 32
+; RV64IM-NEXT: xori a1, a2, 1
+; RV64IM-NEXT: slli a1, a1, 5
; RV64IM-NEXT: bltu a1, a0, .LBB6_2
; RV64IM-NEXT: # %bb.1: # %entry
; RV64IM-NEXT: mv a0, a1
@@ -526,23 +526,23 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
;
; RV32IMZBB-LABEL: select_umax_3:
; RV32IMZBB: # %bb.0: # %entry
-; RV32IMZBB-NEXT: addi a0, a0, -1
-; RV32IMZBB-NEXT: andi a0, a0, 32
+; RV32IMZBB-NEXT: xori a0, a0, 1
+; RV32IMZBB-NEXT: slli a0, a0, 5
; RV32IMZBB-NEXT: maxu a0, a1, a0
; RV32IMZBB-NEXT: ret
;
; RV64IMZBB-LABEL: select_umax_3:
; RV64IMZBB: # %bb.0: # %entry
; RV64IMZBB-NEXT: sext.w a1, a1
-; RV64IMZBB-NEXT: addi a0, a0, -1
-; RV64IMZBB-NEXT: andi a0, a0, 32
+; RV64IMZBB-NEXT: xori a0, a0, 1
+; RV64IMZBB-NEXT: slli a0, a0, 5
; RV64IMZBB-NEXT: maxu a0, a1, a0
; RV64IMZBB-NEXT: ret
;
; RV32IMZICOND-LABEL: select_umax_3:
; RV32IMZICOND: # %bb.0: # %entry
-; RV32IMZICOND-NEXT: addi a0, a0, -1
-; RV32IMZICOND-NEXT: andi a0, a0, 32
+; RV32IMZICOND-NEXT: xori a0, a0, 1
+; RV32IMZICOND-NEXT: slli a0, a0, 5
; RV32IMZICOND-NEXT: sltu a2, a0, a1
; RV32IMZICOND-NEXT: czero.nez a0, a0, a2
; RV32IMZICOND-NEXT: czero.eqz a1, a1, a2
@@ -552,8 +552,8 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV64IMZICOND-LABEL: select_umax_3:
; RV64IMZICOND: # %bb.0: # %entry
; RV64IMZICOND-NEXT: sext.w a1, a1
-; RV64IMZICOND-NEXT: addi a0, a0, -1
-; RV64IMZICOND-NEXT: andi a0, a0, 32
+; RV64IMZICOND-NEXT: xori a0, a0, 1
+; RV64IMZICOND-NEXT: slli a0, a0, 5
; RV64IMZICOND-NEXT: sltu a2, a0, a1
; RV64IMZICOND-NEXT: czero.nez a0, a0, a2
; RV64IMZICOND-NEXT: czero.eqz a1, a1, a2
@@ -562,16 +562,16 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
;
; RV32IMBOTH-LABEL: select_umax_3:
; RV32IMBOTH: # %bb.0: # %entry
-; RV32IMBOTH-NEXT: addi a0, a0, -1
-; RV32IMBOTH-NEXT: andi a0, a0, 32
+; RV32IMBOTH-NEXT: xori a0, a0, 1
+; RV32IMBOTH-NEXT: slli a0, a0, 5
; RV32IMBOTH-NEXT: maxu a0, a1, a0
; RV32IMBOTH-NEXT: ret
;
; RV64IMBOTH-LABEL: select_umax_3:
; RV64IMBOTH: # %bb.0: # %entry
; RV64IMBOTH-NEXT: sext.w a1, a1
-; RV64IMBOTH-NEXT: addi a0, a0, -1
-; RV64IMBOTH-NEXT: andi a0, a0, 32
+; RV64IMBOTH-NEXT: xori a0, a0, 1
+; RV64IMBOTH-NEXT: slli a0, a0, 5
; RV64IMBOTH-NEXT: maxu a0, a1, a0
; RV64IMBOTH-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/Thumb/branchless-cmp.ll b/llvm/test/CodeGen/Thumb/branchless-cmp.ll
index e5bfb87f00c92..49cd59efe9377 100644
--- a/llvm/test/CodeGen/Thumb/branchless-cmp.ll
+++ b/llvm/test/CodeGen/Thumb/branchless-cmp.ll
@@ -57,10 +57,9 @@ define i32 @test3a(i32 %a, i32 %b) {
; CHECK-LABEL: test3a:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: subs r0, r0, r1
-; CHECK-NEXT: beq .LBB4_2
-; CHECK-NEXT: @ %bb.1:
-; CHECK-NEXT: movs r0, #4
-; CHECK-NEXT: .LBB4_2: @ %entry
+; CHECK-NEXT: subs r1, r0, #1
+; CHECK-NEXT: sbcs r0, r1
+; CHECK-NEXT: lsls r0, r0, #2
; CHECK-NEXT: bx lr
entry:
%cmp = icmp eq i32 %a, %b
@@ -88,13 +87,10 @@ entry:
define i32 @test4a(i32 %a, i32 %b) {
; CHECK-LABEL: test4a:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: cmp r0, r1
-; CHECK-NEXT: bne .LBB6_2
-; CHECK-NEXT: @ %bb.1: @ %entry
-; CHECK-NEXT: movs r0, #4
-; CHECK-NEXT: bx lr
-; CHECK-NEXT: .LBB6_2:
-; CHECK-NEXT: movs r0, #0
+; CHECK-NEXT: subs r0, r0, r1
+; CHECK-NEXT: rsbs r1, r0, #0
+; CHECK-NEXT: adcs r1, r0
+; CHECK-NEXT: lsls r0, r1, #2
; CHECK-NEXT: bx lr
entry:
%cmp = icmp ne i32 %a, %b
>From bfe2b65bc45ed6a65d6b830edc8b7174ca5b345e Mon Sep 17 00:00:00 2001
From: Dong JianQiang <dongjianqiang2 at huawei.com>
Date: Fri, 29 May 2026 15:04:36 +0800
Subject: [PATCH 2/5] [RISCV] Reverse select Cond,0,Pow2 fold for C/Zca code
size
The generic DAG combine folds `select Cond, 0, Pow2` into
`(zext (!Cond)) << log2(Pow2)`, which produces `xori 1; slli C` on
RISC-V. However, `xori` can never be compressed to a 2-byte
instruction under the C or Zca extension, whereas the original select
lowering produces `addi -1; andi Pow2` where both instructions
compress.
Add a target-specific DAG combine that reverses this fold when C/Zca
is enabled, converting the post-legalize pattern
`shl (xor (assertzext Cond, i1), 1), C` back to
`select Cond, 0, 1<<C`, allowing the backend to generate the more
compact sequence.
Also move ISD::SHL registration from the hasVInstructions() block to
the unconditional setTargetDAGCombine list so the scalar combine fires
for all targets.
Assisted-By: Claude Opus 4.7 <noreply at anthropic.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 38 ++-
llvm/test/CodeGen/RISCV/select-zbb.ll | 294 ++++++++++++++++++++
2 files changed, 329 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 42a1f120643df..0069a2f195b4d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1888,7 +1888,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setTargetDAGCombine({ISD::INTRINSIC_VOID, ISD::INTRINSIC_W_CHAIN,
ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::MUL,
ISD::AND, ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT,
- ISD::SRA});
+ ISD::SRA, ISD::SHL});
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
if (Subtarget.hasStdExtFOrZfinx())
@@ -1917,7 +1917,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::VP_GATHER,
ISD::VP_SCATTER,
ISD::SRL,
- ISD::SHL,
ISD::STORE,
ISD::SPLAT_VECTOR,
ISD::BUILD_VECTOR,
@@ -21028,6 +21027,40 @@ static SDValue performSHLCombine(SDNode *N,
if (SDValue V = combineOp_VLToVWOp_VL(N, DCI, Subtarget))
return V;
+ SelectionDAG &DAG = DCI.DAG;
+
+ // Reverse the generic fold: select Cond, 0, Pow2 -> (zext (!Cond)) <<
+ // log2(Pow2) back to select Cond, 0, Pow2 when the C or Zca extension is
+ // enabled, because the select lowering produces addi -1; andi Pow2 which
+ // compresses to 2-byte instructions, whereas xori 1 never compresses.
+ //
+ // After legalization, the zext+xor pattern becomes:
+ // shl (xor (assertzext Cond, i1), 1), C
+ if (DCI.isAfterLegalizeDAG() &&
+ (Subtarget.hasStdExtC() || Subtarget.hasStdExtZca())) {
+ EVT VT = N->getValueType(0);
+ if (!VT.isVector()) {
+ SDValue N0 = N->getOperand(0);
+ if (N0.hasOneUse() && N0.getOpcode() == ISD::XOR) {
+ SDValue XorLHS = N0.getOperand(0);
+ SDValue XorRHS = N0.getOperand(1);
+ // Match: xor (assertzext Cond, i1), 1
+ if (isOneConstant(XorRHS) && XorLHS.getOpcode() == ISD::AssertZext &&
+ cast<VTSDNode>(XorLHS.getOperand(1))->getVT() == MVT::i1) {
+ if (auto *ShAmtC = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
+ uint64_t ShAmtVal = ShAmtC->getZExtValue();
+ APInt Pow2 = APInt(VT.getSizeInBits(), 1) << ShAmtVal;
+ SDLoc DL(N);
+ SDValue Cond = XorLHS.getOperand(0);
+ return DAG.getNode(ISD::SELECT, DL, VT, Cond,
+ DAG.getConstant(0, DL, VT),
+ DAG.getConstant(Pow2, DL, VT));
+ }
+ }
+ }
+ }
+ }
+
// (shl (sext x), C) -> (vwmulsu x, 1u << C)
// (shl (zext x), C) -> (vwmulu x, 1u << C)
@@ -21077,7 +21110,6 @@ static SDValue performSHLCombine(SDNode *N,
if (NarrowBits * 2 != VT.getScalarSizeInBits())
return SDValue();
- SelectionDAG &DAG = DCI.DAG;
SDLoc DL(N);
SDValue Passthru, Mask, VL;
switch (N->getOpcode()) {
diff --git a/llvm/test/CodeGen/RISCV/select-zbb.ll b/llvm/test/CodeGen/RISCV/select-zbb.ll
index e8d2bf4704813..5b4602533ec0c 100644
--- a/llvm/test/CodeGen/RISCV/select-zbb.ll
+++ b/llvm/test/CodeGen/RISCV/select-zbb.ll
@@ -7,6 +7,8 @@
; RUN: llc -mtriple=riscv64 -mattr=+m,+zicond -verify-machineinstrs < %s | FileCheck --check-prefixes=RV64IMZICOND %s
; RUN: llc -mtriple=riscv32 -mattr=+m,+zicond,+zbb -verify-machineinstrs < %s | FileCheck --check-prefixes=RV32IMBOTH %s
; RUN: llc -mtriple=riscv64 -mattr=+m,+zicond,+zbb -verify-machineinstrs < %s | FileCheck --check-prefixes=RV64IMBOTH %s
+; RUN: llc -mtriple=riscv32 -mattr=+m,+zbb,+c -verify-machineinstrs < %s | FileCheck --check-prefixes=RV32IMZBBC %s
+; RUN: llc -mtriple=riscv64 -mattr=+m,+zbb,+c -verify-machineinstrs < %s | FileCheck --check-prefixes=RV64IMZBBC %s
define i32 @select_umin_1(i1 zeroext %cond, i32 %a, i32 %b) {
@@ -87,6 +89,22 @@ define i32 @select_umin_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: minu a0, a2, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umin_1:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: addi a0, a0, -1
+; RV32IMZBBC-NEXT: or a0, a0, a1
+; RV32IMZBBC-NEXT: minu a0, a2, a0
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umin_1:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: sext.w a2, a2
+; RV64IMZBBC-NEXT: addi a0, a0, -1
+; RV64IMZBBC-NEXT: or a0, a0, a1
+; RV64IMZBBC-NEXT: sext.w a0, a0
+; RV64IMZBBC-NEXT: minu a0, a2, a0
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -171,6 +189,22 @@ define i32 @select_umin_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: minu a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umin_2:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: neg a0, a0
+; RV32IMZBBC-NEXT: or a0, a0, a2
+; RV32IMZBBC-NEXT: minu a0, a1, a0
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umin_2:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: neg a0, a0
+; RV64IMZBBC-NEXT: or a0, a0, a2
+; RV64IMZBBC-NEXT: sext.w a0, a0
+; RV64IMZBBC-NEXT: minu a0, a1, a0
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -251,6 +285,21 @@ define i32 @select_umin_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: ori a0, a0, 32
; RV64IMBOTH-NEXT: minu a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umin_3:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: neg a0, a0
+; RV32IMZBBC-NEXT: ori a0, a0, 32
+; RV32IMZBBC-NEXT: minu a0, a1, a0
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umin_3:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: neg a0, a0
+; RV64IMZBBC-NEXT: ori a0, a0, 32
+; RV64IMZBBC-NEXT: minu a0, a1, a0
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umin(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -335,6 +384,23 @@ define i32 @select_umin_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: li a1, 128
; RV64IMBOTH-NEXT: minu a0, a0, a1
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umin_4:
+; RV32IMZBBC: # %bb.0:
+; RV32IMZBBC-NEXT: neg a0, a0
+; RV32IMZBBC-NEXT: or a0, a0, a1
+; RV32IMZBBC-NEXT: li a1, 128
+; RV32IMZBBC-NEXT: minu a0, a0, a1
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umin_4:
+; RV64IMZBBC: # %bb.0:
+; RV64IMZBBC-NEXT: neg a0, a0
+; RV64IMZBBC-NEXT: or a0, a0, a1
+; RV64IMZBBC-NEXT: sext.w a0, a0
+; RV64IMZBBC-NEXT: li a1, 128
+; RV64IMZBBC-NEXT: minu a0, a0, a1
+; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.umin(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
@@ -414,6 +480,22 @@ define i32 @select_umax_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: maxu a0, a2, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umax_1:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: neg a0, a0
+; RV32IMZBBC-NEXT: and a0, a0, a1
+; RV32IMZBBC-NEXT: maxu a0, a2, a0
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umax_1:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: sext.w a2, a2
+; RV64IMZBBC-NEXT: neg a0, a0
+; RV64IMZBBC-NEXT: and a0, a0, a1
+; RV64IMZBBC-NEXT: sext.w a0, a0
+; RV64IMZBBC-NEXT: maxu a0, a2, a0
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -494,6 +576,22 @@ define i32 @select_umax_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: maxu a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umax_2:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: addi a0, a0, -1
+; RV32IMZBBC-NEXT: and a0, a0, a2
+; RV32IMZBBC-NEXT: maxu a0, a1, a0
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umax_2:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: addi a0, a0, -1
+; RV64IMZBBC-NEXT: and a0, a0, a2
+; RV64IMZBBC-NEXT: sext.w a0, a0
+; RV64IMZBBC-NEXT: maxu a0, a1, a0
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -574,6 +672,21 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: slli a0, a0, 5
; RV64IMBOTH-NEXT: maxu a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umax_3:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: addi a0, a0, -1
+; RV32IMZBBC-NEXT: andi a0, a0, 32
+; RV32IMZBBC-NEXT: maxu a0, a1, a0
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umax_3:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: addi a0, a0, -1
+; RV64IMZBBC-NEXT: andi a0, a0, 32
+; RV64IMZBBC-NEXT: maxu a0, a1, a0
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umax(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -654,6 +767,23 @@ define i32 @select_umax_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: li a1, 128
; RV64IMBOTH-NEXT: maxu a0, a0, a1
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_umax_4:
+; RV32IMZBBC: # %bb.0:
+; RV32IMZBBC-NEXT: addi a0, a0, -1
+; RV32IMZBBC-NEXT: and a0, a0, a1
+; RV32IMZBBC-NEXT: li a1, 128
+; RV32IMZBBC-NEXT: maxu a0, a0, a1
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_umax_4:
+; RV64IMZBBC: # %bb.0:
+; RV64IMZBBC-NEXT: addi a0, a0, -1
+; RV64IMZBBC-NEXT: and a0, a0, a1
+; RV64IMZBBC-NEXT: sext.w a0, a0
+; RV64IMZBBC-NEXT: li a1, 128
+; RV64IMZBBC-NEXT: maxu a0, a0, a1
+; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.umax(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
@@ -753,6 +883,26 @@ define i32 @select_smin_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.eqz a0, a1, a0
; RV64IMBOTH-NEXT: or a0, a0, a2
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smin_1:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: beqz a0, .LBB8_2
+; RV32IMZBBC-NEXT: # %bb.1:
+; RV32IMZBBC-NEXT: min a2, a1, a2
+; RV32IMZBBC-NEXT: .LBB8_2: # %entry
+; RV32IMZBBC-NEXT: mv a0, a2
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smin_1:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: beqz a0, .LBB8_2
+; RV64IMZBBC-NEXT: # %bb.1:
+; RV64IMZBBC-NEXT: sext.w a2, a2
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: min a2, a1, a2
+; RV64IMZBBC-NEXT: .LBB8_2: # %entry
+; RV64IMZBBC-NEXT: mv a0, a2
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -854,6 +1004,26 @@ define i32 @select_smin_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smin_2:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: bnez a0, .LBB9_2
+; RV32IMZBBC-NEXT: # %bb.1: # %entry
+; RV32IMZBBC-NEXT: min a1, a1, a2
+; RV32IMZBBC-NEXT: .LBB9_2: # %entry
+; RV32IMZBBC-NEXT: mv a0, a1
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smin_2:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: bnez a0, .LBB9_2
+; RV64IMZBBC-NEXT: # %bb.1: # %entry
+; RV64IMZBBC-NEXT: sext.w a2, a2
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: min a1, a1, a2
+; RV64IMZBBC-NEXT: .LBB9_2: # %entry
+; RV64IMZBBC-NEXT: mv a0, a1
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -957,6 +1127,27 @@ define i32 @select_smin_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smin_3:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: bnez a0, .LBB10_2
+; RV32IMZBBC-NEXT: # %bb.1: # %entry
+; RV32IMZBBC-NEXT: li a0, 32
+; RV32IMZBBC-NEXT: min a1, a1, a0
+; RV32IMZBBC-NEXT: .LBB10_2: # %entry
+; RV32IMZBBC-NEXT: mv a0, a1
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smin_3:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: bnez a0, .LBB10_2
+; RV64IMZBBC-NEXT: # %bb.1: # %entry
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: li a0, 32
+; RV64IMZBBC-NEXT: min a1, a1, a0
+; RV64IMZBBC-NEXT: .LBB10_2: # %entry
+; RV64IMZBBC-NEXT: mv a0, a1
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smin(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1055,6 +1246,27 @@ define i32 @select_smin_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: czero.nez a0, a1, a0
; RV64IMBOTH-NEXT: addi a0, a0, 128
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smin_4:
+; RV32IMZBBC: # %bb.0:
+; RV32IMZBBC-NEXT: mv a2, a0
+; RV32IMZBBC-NEXT: li a0, 128
+; RV32IMZBBC-NEXT: bnez a2, .LBB11_2
+; RV32IMZBBC-NEXT: # %bb.1:
+; RV32IMZBBC-NEXT: min a0, a1, a0
+; RV32IMZBBC-NEXT: .LBB11_2:
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smin_4:
+; RV64IMZBBC: # %bb.0:
+; RV64IMZBBC-NEXT: mv a2, a0
+; RV64IMZBBC-NEXT: li a0, 128
+; RV64IMZBBC-NEXT: bnez a2, .LBB11_2
+; RV64IMZBBC-NEXT: # %bb.1:
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: min a0, a1, a0
+; RV64IMZBBC-NEXT: .LBB11_2:
+; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.smin(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
@@ -1154,6 +1366,26 @@ define i32 @select_smax_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.eqz a0, a1, a0
; RV64IMBOTH-NEXT: or a0, a0, a2
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smax_1:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: beqz a0, .LBB12_2
+; RV32IMZBBC-NEXT: # %bb.1:
+; RV32IMZBBC-NEXT: max a2, a1, a2
+; RV32IMZBBC-NEXT: .LBB12_2: # %entry
+; RV32IMZBBC-NEXT: mv a0, a2
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smax_1:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: beqz a0, .LBB12_2
+; RV64IMZBBC-NEXT: # %bb.1:
+; RV64IMZBBC-NEXT: sext.w a2, a2
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: max a2, a1, a2
+; RV64IMZBBC-NEXT: .LBB12_2: # %entry
+; RV64IMZBBC-NEXT: mv a0, a2
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -1255,6 +1487,26 @@ define i32 @select_smax_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smax_2:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: bnez a0, .LBB13_2
+; RV32IMZBBC-NEXT: # %bb.1: # %entry
+; RV32IMZBBC-NEXT: max a1, a1, a2
+; RV32IMZBBC-NEXT: .LBB13_2: # %entry
+; RV32IMZBBC-NEXT: mv a0, a1
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smax_2:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: bnez a0, .LBB13_2
+; RV64IMZBBC-NEXT: # %bb.1: # %entry
+; RV64IMZBBC-NEXT: sext.w a2, a2
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: max a1, a1, a2
+; RV64IMZBBC-NEXT: .LBB13_2: # %entry
+; RV64IMZBBC-NEXT: mv a0, a1
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1358,6 +1610,27 @@ define i32 @select_smax_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smax_3:
+; RV32IMZBBC: # %bb.0: # %entry
+; RV32IMZBBC-NEXT: bnez a0, .LBB14_2
+; RV32IMZBBC-NEXT: # %bb.1: # %entry
+; RV32IMZBBC-NEXT: li a0, 32
+; RV32IMZBBC-NEXT: max a1, a1, a0
+; RV32IMZBBC-NEXT: .LBB14_2: # %entry
+; RV32IMZBBC-NEXT: mv a0, a1
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smax_3:
+; RV64IMZBBC: # %bb.0: # %entry
+; RV64IMZBBC-NEXT: bnez a0, .LBB14_2
+; RV64IMZBBC-NEXT: # %bb.1: # %entry
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: li a0, 32
+; RV64IMZBBC-NEXT: max a1, a1, a0
+; RV64IMZBBC-NEXT: .LBB14_2: # %entry
+; RV64IMZBBC-NEXT: mv a0, a1
+; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smax(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1456,6 +1729,27 @@ define i32 @select_smax_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: czero.nez a0, a1, a0
; RV64IMBOTH-NEXT: addi a0, a0, 128
; RV64IMBOTH-NEXT: ret
+;
+; RV32IMZBBC-LABEL: select_smax_4:
+; RV32IMZBBC: # %bb.0:
+; RV32IMZBBC-NEXT: mv a2, a0
+; RV32IMZBBC-NEXT: li a0, 128
+; RV32IMZBBC-NEXT: bnez a2, .LBB15_2
+; RV32IMZBBC-NEXT: # %bb.1:
+; RV32IMZBBC-NEXT: max a0, a1, a0
+; RV32IMZBBC-NEXT: .LBB15_2:
+; RV32IMZBBC-NEXT: ret
+;
+; RV64IMZBBC-LABEL: select_smax_4:
+; RV64IMZBBC: # %bb.0:
+; RV64IMZBBC-NEXT: mv a2, a0
+; RV64IMZBBC-NEXT: li a0, 128
+; RV64IMZBBC-NEXT: bnez a2, .LBB15_2
+; RV64IMZBBC-NEXT: # %bb.1:
+; RV64IMZBBC-NEXT: sext.w a1, a1
+; RV64IMZBBC-NEXT: max a0, a1, a0
+; RV64IMZBBC-NEXT: .LBB15_2:
+; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.smax(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
>From 55a5abcbb1ff7a45203b63fe7d0855eb780725eb Mon Sep 17 00:00:00 2001
From: Dong JianQiang <dongjianqiang2 at huawei.com>
Date: Fri, 29 May 2026 23:52:45 +0800
Subject: [PATCH 3/5] [RISCV] Use SDPatternMatch in reverse select fold, NFC
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 32 +++++++++------------
1 file changed, 13 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0069a2f195b4d..af868376c047b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21038,26 +21038,20 @@ static SDValue performSHLCombine(SDNode *N,
// shl (xor (assertzext Cond, i1), 1), C
if (DCI.isAfterLegalizeDAG() &&
(Subtarget.hasStdExtC() || Subtarget.hasStdExtZca())) {
+ using namespace SDPatternMatch;
EVT VT = N->getValueType(0);
- if (!VT.isVector()) {
- SDValue N0 = N->getOperand(0);
- if (N0.hasOneUse() && N0.getOpcode() == ISD::XOR) {
- SDValue XorLHS = N0.getOperand(0);
- SDValue XorRHS = N0.getOperand(1);
- // Match: xor (assertzext Cond, i1), 1
- if (isOneConstant(XorRHS) && XorLHS.getOpcode() == ISD::AssertZext &&
- cast<VTSDNode>(XorLHS.getOperand(1))->getVT() == MVT::i1) {
- if (auto *ShAmtC = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
- uint64_t ShAmtVal = ShAmtC->getZExtValue();
- APInt Pow2 = APInt(VT.getSizeInBits(), 1) << ShAmtVal;
- SDLoc DL(N);
- SDValue Cond = XorLHS.getOperand(0);
- return DAG.getNode(ISD::SELECT, DL, VT, Cond,
- DAG.getConstant(0, DL, VT),
- DAG.getConstant(Pow2, DL, VT));
- }
- }
- }
+ SDValue Cond, ZextVTOp;
+ uint64_t ShAmtVal;
+ if (!VT.isVector() &&
+ sd_match(N, m_Shl(m_OneUse(m_Xor(m_Node(ISD::AssertZext, m_Value(Cond),
+ m_Value(ZextVTOp)),
+ m_One())),
+ m_ConstInt(ShAmtVal))) &&
+ cast<VTSDNode>(ZextVTOp)->getVT() == MVT::i1) {
+ APInt Pow2 = APInt(VT.getSizeInBits(), 1) << ShAmtVal;
+ SDLoc DL(N);
+ return DAG.getNode(ISD::SELECT, DL, VT, Cond, DAG.getConstant(0, DL, VT),
+ DAG.getConstant(Pow2, DL, VT));
}
}
>From 89dd2c039ac161f944af96595f24a4b175c11bd8 Mon Sep 17 00:00:00 2001
From: Dong JianQiang <dongjianqiang2 at huawei.com>
Date: Sat, 30 May 2026 02:28:39 +0800
Subject: [PATCH 4/5] [RISCV] Handle ZERO_EXTEND in reverse select 0,Pow2
combine
The original reverse fold only matched AssertZext (function arguments).
Extend it to also match ZERO_EXTEND from i1 to handle conditions coming
from setcc/trunc sources. Also replace hasStdExtC() || hasStdExtZca()
with just hasStdExtZca(), and use APInt::getOneBitSet.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 27 ++++++++++++---------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index af868376c047b..4bd7ec93abf2b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21030,25 +21030,30 @@ static SDValue performSHLCombine(SDNode *N,
SelectionDAG &DAG = DCI.DAG;
// Reverse the generic fold: select Cond, 0, Pow2 -> (zext (!Cond)) <<
- // log2(Pow2) back to select Cond, 0, Pow2 when the C or Zca extension is
+ // log2(Pow2) back to select Cond, 0, Pow2 when the Zca extension is
// enabled, because the select lowering produces addi -1; andi Pow2 which
// compresses to 2-byte instructions, whereas xori 1 never compresses.
//
// After legalization, the zext+xor pattern becomes:
- // shl (xor (assertzext Cond, i1), 1), C
- if (DCI.isAfterLegalizeDAG() &&
- (Subtarget.hasStdExtC() || Subtarget.hasStdExtZca())) {
+ // shl (xor (bool), 1), C
+ if (DCI.isAfterLegalizeDAG() && Subtarget.hasStdExtZca()) {
using namespace SDPatternMatch;
EVT VT = N->getValueType(0);
- SDValue Cond, ZextVTOp;
+ SDValue X;
uint64_t ShAmtVal;
if (!VT.isVector() &&
- sd_match(N, m_Shl(m_OneUse(m_Xor(m_Node(ISD::AssertZext, m_Value(Cond),
- m_Value(ZextVTOp)),
- m_One())),
- m_ConstInt(ShAmtVal))) &&
- cast<VTSDNode>(ZextVTOp)->getVT() == MVT::i1) {
- APInt Pow2 = APInt(VT.getSizeInBits(), 1) << ShAmtVal;
+ sd_match(N, m_Shl(m_OneUse(m_Xor(m_Value(X), m_One())),
+ m_ConstInt(ShAmtVal)))) {
+ // X must be zero-extended from i1: either AssertZext (function args)
+ // or ZERO_EXTEND (setcc/trunc sources).
+ SDValue Cond;
+ if (X.getOpcode() == ISD::AssertZext &&
+ cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i1)
+ Cond = X.getOperand(0);
+ else if (!sd_match(X, m_ZExt(m_Value(Cond))))
+ return SDValue();
+
+ APInt Pow2 = APInt::getOneBitSet(VT.getSizeInBits(), ShAmtVal);
SDLoc DL(N);
return DAG.getNode(ISD::SELECT, DL, VT, Cond, DAG.getConstant(0, DL, VT),
DAG.getConstant(Pow2, DL, VT));
>From 88edef57e8bb2ae63d3341bc184859383d53f600 Mon Sep 17 00:00:00 2001
From: Dong JianQiang <dongjianqiang2 at huawei.com>
Date: Fri, 5 Jun 2026 18:29:29 +0800
Subject: [PATCH 5/5] [RISCV] Use computeKnownBits in reverse select 0,Pow2
combine
Simplify the reverse fold by using computeKnownBits to detect zero-extended
i1 values, which handles AssertZext, setcc results and other bool-like
patterns uniformly. Also drop the hasStdExtZca() guard and run the fold
unconditionally to minimize output differences between configurations.
Assisted-By: Claude Opus 4.7 <noreply at anthropic.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 24 +-
llvm/test/CodeGen/RISCV/select-const.ll | 22 +-
llvm/test/CodeGen/RISCV/select-zbb.ll | 326 +-----------------
llvm/test/CodeGen/RISCV/select.ll | 52 +--
.../CodeGen/RISCV/selectcc-to-shiftand.ll | 4 +-
5 files changed, 64 insertions(+), 364 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4bd7ec93abf2b..cc5bf633dce69 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21030,13 +21030,12 @@ static SDValue performSHLCombine(SDNode *N,
SelectionDAG &DAG = DCI.DAG;
// Reverse the generic fold: select Cond, 0, Pow2 -> (zext (!Cond)) <<
- // log2(Pow2) back to select Cond, 0, Pow2 when the Zca extension is
- // enabled, because the select lowering produces addi -1; andi Pow2 which
- // compresses to 2-byte instructions, whereas xori 1 never compresses.
+ // log2(Pow2) back to select Cond, 0, Pow2, because the select lowering
+ // produces addi -1; andi Pow2 which is preferable to xori 1; slli C.
//
// After legalization, the zext+xor pattern becomes:
// shl (xor (bool), 1), C
- if (DCI.isAfterLegalizeDAG() && Subtarget.hasStdExtZca()) {
+ if (DCI.isAfterLegalizeDAG()) {
using namespace SDPatternMatch;
EVT VT = N->getValueType(0);
SDValue X;
@@ -21044,19 +21043,12 @@ static SDValue performSHLCombine(SDNode *N,
if (!VT.isVector() &&
sd_match(N, m_Shl(m_OneUse(m_Xor(m_Value(X), m_One())),
m_ConstInt(ShAmtVal)))) {
- // X must be zero-extended from i1: either AssertZext (function args)
- // or ZERO_EXTEND (setcc/trunc sources).
- SDValue Cond;
- if (X.getOpcode() == ISD::AssertZext &&
- cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i1)
- Cond = X.getOperand(0);
- else if (!sd_match(X, m_ZExt(m_Value(Cond))))
- return SDValue();
-
- APInt Pow2 = APInt::getOneBitSet(VT.getSizeInBits(), ShAmtVal);
SDLoc DL(N);
- return DAG.getNode(ISD::SELECT, DL, VT, Cond, DAG.getConstant(0, DL, VT),
- DAG.getConstant(Pow2, DL, VT));
+ if (DAG.computeKnownBits(X).countMaxActiveBits() <= 1) {
+ APInt Pow2 = APInt::getOneBitSet(VT.getSizeInBits(), ShAmtVal);
+ return DAG.getNode(ISD::SELECT, DL, VT, X, DAG.getConstant(0, DL, VT),
+ DAG.getConstant(Pow2, DL, VT));
+ }
}
}
diff --git a/llvm/test/CodeGen/RISCV/select-const.ll b/llvm/test/CodeGen/RISCV/select-const.ll
index 5069924eba5b6..c25b3979c2f46 100644
--- a/llvm/test/CodeGen/RISCV/select-const.ll
+++ b/llvm/test/CodeGen/RISCV/select-const.ll
@@ -102,8 +102,8 @@ define signext i32 @select_const_int_harder(i1 zeroext %a) nounwind {
;
; RV32ZICOND-LABEL: select_const_int_harder:
; RV32ZICOND: # %bb.0:
-; RV32ZICOND-NEXT: xori a0, a0, 1
-; RV32ZICOND-NEXT: slli a0, a0, 5
+; RV32ZICOND-NEXT: addi a0, a0, -1
+; RV32ZICOND-NEXT: andi a0, a0, 32
; RV32ZICOND-NEXT: addi a0, a0, 6
; RV32ZICOND-NEXT: ret
;
@@ -135,8 +135,8 @@ define signext i32 @select_const_int_harder(i1 zeroext %a) nounwind {
;
; RV64ZICOND-LABEL: select_const_int_harder:
; RV64ZICOND: # %bb.0:
-; RV64ZICOND-NEXT: xori a0, a0, 1
-; RV64ZICOND-NEXT: slli a0, a0, 5
+; RV64ZICOND-NEXT: addi a0, a0, -1
+; RV64ZICOND-NEXT: andi a0, a0, 32
; RV64ZICOND-NEXT: addiw a0, a0, 6
; RV64ZICOND-NEXT: ret
%1 = select i1 %a, i32 6, i32 38
@@ -797,7 +797,8 @@ define i32 @diff_shl_addi(i32 signext %x) {
; RV32ZICOND-LABEL: diff_shl_addi:
; RV32ZICOND: # %bb.0:
; RV32ZICOND-NEXT: srli a0, a0, 31
-; RV32ZICOND-NEXT: slli a0, a0, 14
+; RV32ZICOND-NEXT: lui a1, 4
+; RV32ZICOND-NEXT: czero.eqz a0, a1, a0
; RV32ZICOND-NEXT: addi a0, a0, 25
; RV32ZICOND-NEXT: ret
;
@@ -837,7 +838,8 @@ define i32 @diff_shl_addi(i32 signext %x) {
; RV64ZICOND-LABEL: diff_shl_addi:
; RV64ZICOND: # %bb.0:
; RV64ZICOND-NEXT: srli a0, a0, 63
-; RV64ZICOND-NEXT: slli a0, a0, 14
+; RV64ZICOND-NEXT: lui a1, 4
+; RV64ZICOND-NEXT: czero.eqz a0, a1, a0
; RV64ZICOND-NEXT: addiw a0, a0, 25
; RV64ZICOND-NEXT: ret
%cmp = icmp sgt i32 %x, -1
@@ -871,8 +873,8 @@ define i32 @diff_shl_addi2(i32 signext %x) {
; RV32ZICOND-LABEL: diff_shl_addi2:
; RV32ZICOND: # %bb.0:
; RV32ZICOND-NEXT: srli a0, a0, 31
-; RV32ZICOND-NEXT: xori a0, a0, 1
-; RV32ZICOND-NEXT: slli a0, a0, 14
+; RV32ZICOND-NEXT: lui a1, 4
+; RV32ZICOND-NEXT: czero.nez a0, a1, a0
; RV32ZICOND-NEXT: addi a0, a0, 25
; RV32ZICOND-NEXT: ret
;
@@ -912,8 +914,8 @@ define i32 @diff_shl_addi2(i32 signext %x) {
; RV64ZICOND-LABEL: diff_shl_addi2:
; RV64ZICOND: # %bb.0:
; RV64ZICOND-NEXT: srli a0, a0, 63
-; RV64ZICOND-NEXT: xori a0, a0, 1
-; RV64ZICOND-NEXT: slli a0, a0, 14
+; RV64ZICOND-NEXT: lui a1, 4
+; RV64ZICOND-NEXT: czero.nez a0, a1, a0
; RV64ZICOND-NEXT: addiw a0, a0, 25
; RV64ZICOND-NEXT: ret
%cmp = icmp sgt i32 %x, -1
diff --git a/llvm/test/CodeGen/RISCV/select-zbb.ll b/llvm/test/CodeGen/RISCV/select-zbb.ll
index 5b4602533ec0c..efc3f46376b4e 100644
--- a/llvm/test/CodeGen/RISCV/select-zbb.ll
+++ b/llvm/test/CodeGen/RISCV/select-zbb.ll
@@ -7,8 +7,6 @@
; RUN: llc -mtriple=riscv64 -mattr=+m,+zicond -verify-machineinstrs < %s | FileCheck --check-prefixes=RV64IMZICOND %s
; RUN: llc -mtriple=riscv32 -mattr=+m,+zicond,+zbb -verify-machineinstrs < %s | FileCheck --check-prefixes=RV32IMBOTH %s
; RUN: llc -mtriple=riscv64 -mattr=+m,+zicond,+zbb -verify-machineinstrs < %s | FileCheck --check-prefixes=RV64IMBOTH %s
-; RUN: llc -mtriple=riscv32 -mattr=+m,+zbb,+c -verify-machineinstrs < %s | FileCheck --check-prefixes=RV32IMZBBC %s
-; RUN: llc -mtriple=riscv64 -mattr=+m,+zbb,+c -verify-machineinstrs < %s | FileCheck --check-prefixes=RV64IMZBBC %s
define i32 @select_umin_1(i1 zeroext %cond, i32 %a, i32 %b) {
@@ -89,22 +87,6 @@ define i32 @select_umin_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: minu a0, a2, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umin_1:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: addi a0, a0, -1
-; RV32IMZBBC-NEXT: or a0, a0, a1
-; RV32IMZBBC-NEXT: minu a0, a2, a0
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umin_1:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: sext.w a2, a2
-; RV64IMZBBC-NEXT: addi a0, a0, -1
-; RV64IMZBBC-NEXT: or a0, a0, a1
-; RV64IMZBBC-NEXT: sext.w a0, a0
-; RV64IMZBBC-NEXT: minu a0, a2, a0
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -189,22 +171,6 @@ define i32 @select_umin_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: minu a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umin_2:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: neg a0, a0
-; RV32IMZBBC-NEXT: or a0, a0, a2
-; RV32IMZBBC-NEXT: minu a0, a1, a0
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umin_2:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: neg a0, a0
-; RV64IMZBBC-NEXT: or a0, a0, a2
-; RV64IMZBBC-NEXT: sext.w a0, a0
-; RV64IMZBBC-NEXT: minu a0, a1, a0
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -285,21 +251,6 @@ define i32 @select_umin_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: ori a0, a0, 32
; RV64IMBOTH-NEXT: minu a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umin_3:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: neg a0, a0
-; RV32IMZBBC-NEXT: ori a0, a0, 32
-; RV32IMZBBC-NEXT: minu a0, a1, a0
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umin_3:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: neg a0, a0
-; RV64IMZBBC-NEXT: ori a0, a0, 32
-; RV64IMZBBC-NEXT: minu a0, a1, a0
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umin(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -384,23 +335,6 @@ define i32 @select_umin_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: li a1, 128
; RV64IMBOTH-NEXT: minu a0, a0, a1
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umin_4:
-; RV32IMZBBC: # %bb.0:
-; RV32IMZBBC-NEXT: neg a0, a0
-; RV32IMZBBC-NEXT: or a0, a0, a1
-; RV32IMZBBC-NEXT: li a1, 128
-; RV32IMZBBC-NEXT: minu a0, a0, a1
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umin_4:
-; RV64IMZBBC: # %bb.0:
-; RV64IMZBBC-NEXT: neg a0, a0
-; RV64IMZBBC-NEXT: or a0, a0, a1
-; RV64IMZBBC-NEXT: sext.w a0, a0
-; RV64IMZBBC-NEXT: li a1, 128
-; RV64IMZBBC-NEXT: minu a0, a0, a1
-; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.umin(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
@@ -480,22 +414,6 @@ define i32 @select_umax_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: maxu a0, a2, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umax_1:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: neg a0, a0
-; RV32IMZBBC-NEXT: and a0, a0, a1
-; RV32IMZBBC-NEXT: maxu a0, a2, a0
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umax_1:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: sext.w a2, a2
-; RV64IMZBBC-NEXT: neg a0, a0
-; RV64IMZBBC-NEXT: and a0, a0, a1
-; RV64IMZBBC-NEXT: sext.w a0, a0
-; RV64IMZBBC-NEXT: maxu a0, a2, a0
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -576,22 +494,6 @@ define i32 @select_umax_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: sext.w a0, a0
; RV64IMBOTH-NEXT: maxu a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umax_2:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: addi a0, a0, -1
-; RV32IMZBBC-NEXT: and a0, a0, a2
-; RV32IMZBBC-NEXT: maxu a0, a1, a0
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umax_2:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: addi a0, a0, -1
-; RV64IMZBBC-NEXT: and a0, a0, a2
-; RV64IMZBBC-NEXT: sext.w a0, a0
-; RV64IMZBBC-NEXT: maxu a0, a1, a0
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -601,8 +503,8 @@ entry:
define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV32IM-LABEL: select_umax_3:
; RV32IM: # %bb.0: # %entry
-; RV32IM-NEXT: xori a2, a0, 1
-; RV32IM-NEXT: slli a2, a2, 5
+; RV32IM-NEXT: addi a0, a0, -1
+; RV32IM-NEXT: andi a2, a0, 32
; RV32IM-NEXT: mv a0, a1
; RV32IM-NEXT: bltu a2, a1, .LBB6_2
; RV32IM-NEXT: # %bb.1: # %entry
@@ -614,8 +516,8 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV64IM: # %bb.0: # %entry
; RV64IM-NEXT: mv a2, a0
; RV64IM-NEXT: sext.w a0, a1
-; RV64IM-NEXT: xori a1, a2, 1
-; RV64IM-NEXT: slli a1, a1, 5
+; RV64IM-NEXT: addi a2, a2, -1
+; RV64IM-NEXT: andi a1, a2, 32
; RV64IM-NEXT: bltu a1, a0, .LBB6_2
; RV64IM-NEXT: # %bb.1: # %entry
; RV64IM-NEXT: mv a0, a1
@@ -624,23 +526,23 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
;
; RV32IMZBB-LABEL: select_umax_3:
; RV32IMZBB: # %bb.0: # %entry
-; RV32IMZBB-NEXT: xori a0, a0, 1
-; RV32IMZBB-NEXT: slli a0, a0, 5
+; RV32IMZBB-NEXT: addi a0, a0, -1
+; RV32IMZBB-NEXT: andi a0, a0, 32
; RV32IMZBB-NEXT: maxu a0, a1, a0
; RV32IMZBB-NEXT: ret
;
; RV64IMZBB-LABEL: select_umax_3:
; RV64IMZBB: # %bb.0: # %entry
; RV64IMZBB-NEXT: sext.w a1, a1
-; RV64IMZBB-NEXT: xori a0, a0, 1
-; RV64IMZBB-NEXT: slli a0, a0, 5
+; RV64IMZBB-NEXT: addi a0, a0, -1
+; RV64IMZBB-NEXT: andi a0, a0, 32
; RV64IMZBB-NEXT: maxu a0, a1, a0
; RV64IMZBB-NEXT: ret
;
; RV32IMZICOND-LABEL: select_umax_3:
; RV32IMZICOND: # %bb.0: # %entry
-; RV32IMZICOND-NEXT: xori a0, a0, 1
-; RV32IMZICOND-NEXT: slli a0, a0, 5
+; RV32IMZICOND-NEXT: addi a0, a0, -1
+; RV32IMZICOND-NEXT: andi a0, a0, 32
; RV32IMZICOND-NEXT: sltu a2, a0, a1
; RV32IMZICOND-NEXT: czero.nez a0, a0, a2
; RV32IMZICOND-NEXT: czero.eqz a1, a1, a2
@@ -650,8 +552,8 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
; RV64IMZICOND-LABEL: select_umax_3:
; RV64IMZICOND: # %bb.0: # %entry
; RV64IMZICOND-NEXT: sext.w a1, a1
-; RV64IMZICOND-NEXT: xori a0, a0, 1
-; RV64IMZICOND-NEXT: slli a0, a0, 5
+; RV64IMZICOND-NEXT: addi a0, a0, -1
+; RV64IMZICOND-NEXT: andi a0, a0, 32
; RV64IMZICOND-NEXT: sltu a2, a0, a1
; RV64IMZICOND-NEXT: czero.nez a0, a0, a2
; RV64IMZICOND-NEXT: czero.eqz a1, a1, a2
@@ -660,33 +562,18 @@ define i32 @select_umax_3(i1 zeroext %cond, i32 %a) {
;
; RV32IMBOTH-LABEL: select_umax_3:
; RV32IMBOTH: # %bb.0: # %entry
-; RV32IMBOTH-NEXT: xori a0, a0, 1
-; RV32IMBOTH-NEXT: slli a0, a0, 5
+; RV32IMBOTH-NEXT: addi a0, a0, -1
+; RV32IMBOTH-NEXT: andi a0, a0, 32
; RV32IMBOTH-NEXT: maxu a0, a1, a0
; RV32IMBOTH-NEXT: ret
;
; RV64IMBOTH-LABEL: select_umax_3:
; RV64IMBOTH: # %bb.0: # %entry
; RV64IMBOTH-NEXT: sext.w a1, a1
-; RV64IMBOTH-NEXT: xori a0, a0, 1
-; RV64IMBOTH-NEXT: slli a0, a0, 5
+; RV64IMBOTH-NEXT: addi a0, a0, -1
+; RV64IMBOTH-NEXT: andi a0, a0, 32
; RV64IMBOTH-NEXT: maxu a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umax_3:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: addi a0, a0, -1
-; RV32IMZBBC-NEXT: andi a0, a0, 32
-; RV32IMZBBC-NEXT: maxu a0, a1, a0
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umax_3:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: addi a0, a0, -1
-; RV64IMZBBC-NEXT: andi a0, a0, 32
-; RV64IMZBBC-NEXT: maxu a0, a1, a0
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.umax(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -767,23 +654,6 @@ define i32 @select_umax_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: li a1, 128
; RV64IMBOTH-NEXT: maxu a0, a0, a1
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_umax_4:
-; RV32IMZBBC: # %bb.0:
-; RV32IMZBBC-NEXT: addi a0, a0, -1
-; RV32IMZBBC-NEXT: and a0, a0, a1
-; RV32IMZBBC-NEXT: li a1, 128
-; RV32IMZBBC-NEXT: maxu a0, a0, a1
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_umax_4:
-; RV64IMZBBC: # %bb.0:
-; RV64IMZBBC-NEXT: addi a0, a0, -1
-; RV64IMZBBC-NEXT: and a0, a0, a1
-; RV64IMZBBC-NEXT: sext.w a0, a0
-; RV64IMZBBC-NEXT: li a1, 128
-; RV64IMZBBC-NEXT: maxu a0, a0, a1
-; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.umax(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
@@ -883,26 +753,6 @@ define i32 @select_smin_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.eqz a0, a1, a0
; RV64IMBOTH-NEXT: or a0, a0, a2
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smin_1:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: beqz a0, .LBB8_2
-; RV32IMZBBC-NEXT: # %bb.1:
-; RV32IMZBBC-NEXT: min a2, a1, a2
-; RV32IMZBBC-NEXT: .LBB8_2: # %entry
-; RV32IMZBBC-NEXT: mv a0, a2
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smin_1:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: beqz a0, .LBB8_2
-; RV64IMZBBC-NEXT: # %bb.1:
-; RV64IMZBBC-NEXT: sext.w a2, a2
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: min a2, a1, a2
-; RV64IMZBBC-NEXT: .LBB8_2: # %entry
-; RV64IMZBBC-NEXT: mv a0, a2
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -1004,26 +854,6 @@ define i32 @select_smin_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smin_2:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: bnez a0, .LBB9_2
-; RV32IMZBBC-NEXT: # %bb.1: # %entry
-; RV32IMZBBC-NEXT: min a1, a1, a2
-; RV32IMZBBC-NEXT: .LBB9_2: # %entry
-; RV32IMZBBC-NEXT: mv a0, a1
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smin_2:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: bnez a0, .LBB9_2
-; RV64IMZBBC-NEXT: # %bb.1: # %entry
-; RV64IMZBBC-NEXT: sext.w a2, a2
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: min a1, a1, a2
-; RV64IMZBBC-NEXT: .LBB9_2: # %entry
-; RV64IMZBBC-NEXT: mv a0, a1
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smin(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1127,27 +957,6 @@ define i32 @select_smin_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smin_3:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: bnez a0, .LBB10_2
-; RV32IMZBBC-NEXT: # %bb.1: # %entry
-; RV32IMZBBC-NEXT: li a0, 32
-; RV32IMZBBC-NEXT: min a1, a1, a0
-; RV32IMZBBC-NEXT: .LBB10_2: # %entry
-; RV32IMZBBC-NEXT: mv a0, a1
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smin_3:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: bnez a0, .LBB10_2
-; RV64IMZBBC-NEXT: # %bb.1: # %entry
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: li a0, 32
-; RV64IMZBBC-NEXT: min a1, a1, a0
-; RV64IMZBBC-NEXT: .LBB10_2: # %entry
-; RV64IMZBBC-NEXT: mv a0, a1
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smin(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1246,27 +1055,6 @@ define i32 @select_smin_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: czero.nez a0, a1, a0
; RV64IMBOTH-NEXT: addi a0, a0, 128
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smin_4:
-; RV32IMZBBC: # %bb.0:
-; RV32IMZBBC-NEXT: mv a2, a0
-; RV32IMZBBC-NEXT: li a0, 128
-; RV32IMZBBC-NEXT: bnez a2, .LBB11_2
-; RV32IMZBBC-NEXT: # %bb.1:
-; RV32IMZBBC-NEXT: min a0, a1, a0
-; RV32IMZBBC-NEXT: .LBB11_2:
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smin_4:
-; RV64IMZBBC: # %bb.0:
-; RV64IMZBBC-NEXT: mv a2, a0
-; RV64IMZBBC-NEXT: li a0, 128
-; RV64IMZBBC-NEXT: bnez a2, .LBB11_2
-; RV64IMZBBC-NEXT: # %bb.1:
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: min a0, a1, a0
-; RV64IMZBBC-NEXT: .LBB11_2:
-; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.smin(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
@@ -1366,26 +1154,6 @@ define i32 @select_smax_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.eqz a0, a1, a0
; RV64IMBOTH-NEXT: or a0, a0, a2
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smax_1:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: beqz a0, .LBB12_2
-; RV32IMZBBC-NEXT: # %bb.1:
-; RV32IMZBBC-NEXT: max a2, a1, a2
-; RV32IMZBBC-NEXT: .LBB12_2: # %entry
-; RV32IMZBBC-NEXT: mv a0, a2
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smax_1:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: beqz a0, .LBB12_2
-; RV64IMZBBC-NEXT: # %bb.1:
-; RV64IMZBBC-NEXT: sext.w a2, a2
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: max a2, a1, a2
-; RV64IMZBBC-NEXT: .LBB12_2: # %entry
-; RV64IMZBBC-NEXT: mv a0, a2
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %c, i32 %b
@@ -1487,26 +1255,6 @@ define i32 @select_smax_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smax_2:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: bnez a0, .LBB13_2
-; RV32IMZBBC-NEXT: # %bb.1: # %entry
-; RV32IMZBBC-NEXT: max a1, a1, a2
-; RV32IMZBBC-NEXT: .LBB13_2: # %entry
-; RV32IMZBBC-NEXT: mv a0, a1
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smax_2:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: bnez a0, .LBB13_2
-; RV64IMZBBC-NEXT: # %bb.1: # %entry
-; RV64IMZBBC-NEXT: sext.w a2, a2
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: max a1, a1, a2
-; RV64IMZBBC-NEXT: .LBB13_2: # %entry
-; RV64IMZBBC-NEXT: mv a0, a1
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smax(i32 %a, i32 %b)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1610,27 +1358,6 @@ define i32 @select_smax_3(i1 zeroext %cond, i32 %a) {
; RV64IMBOTH-NEXT: czero.nez a0, a2, a0
; RV64IMBOTH-NEXT: or a0, a1, a0
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smax_3:
-; RV32IMZBBC: # %bb.0: # %entry
-; RV32IMZBBC-NEXT: bnez a0, .LBB14_2
-; RV32IMZBBC-NEXT: # %bb.1: # %entry
-; RV32IMZBBC-NEXT: li a0, 32
-; RV32IMZBBC-NEXT: max a1, a1, a0
-; RV32IMZBBC-NEXT: .LBB14_2: # %entry
-; RV32IMZBBC-NEXT: mv a0, a1
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smax_3:
-; RV64IMZBBC: # %bb.0: # %entry
-; RV64IMZBBC-NEXT: bnez a0, .LBB14_2
-; RV64IMZBBC-NEXT: # %bb.1: # %entry
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: li a0, 32
-; RV64IMZBBC-NEXT: max a1, a1, a0
-; RV64IMZBBC-NEXT: .LBB14_2: # %entry
-; RV64IMZBBC-NEXT: mv a0, a1
-; RV64IMZBBC-NEXT: ret
entry:
%c = call i32 @llvm.smax(i32 %a, i32 32)
%res = select i1 %cond, i32 %a, i32 %c
@@ -1729,27 +1456,6 @@ define i32 @select_smax_4(i1 zeroext %cond, i32 %x) {
; RV64IMBOTH-NEXT: czero.nez a0, a1, a0
; RV64IMBOTH-NEXT: addi a0, a0, 128
; RV64IMBOTH-NEXT: ret
-;
-; RV32IMZBBC-LABEL: select_smax_4:
-; RV32IMZBBC: # %bb.0:
-; RV32IMZBBC-NEXT: mv a2, a0
-; RV32IMZBBC-NEXT: li a0, 128
-; RV32IMZBBC-NEXT: bnez a2, .LBB15_2
-; RV32IMZBBC-NEXT: # %bb.1:
-; RV32IMZBBC-NEXT: max a0, a1, a0
-; RV32IMZBBC-NEXT: .LBB15_2:
-; RV32IMZBBC-NEXT: ret
-;
-; RV64IMZBBC-LABEL: select_smax_4:
-; RV64IMZBBC: # %bb.0:
-; RV64IMZBBC-NEXT: mv a2, a0
-; RV64IMZBBC-NEXT: li a0, 128
-; RV64IMZBBC-NEXT: bnez a2, .LBB15_2
-; RV64IMZBBC-NEXT: # %bb.1:
-; RV64IMZBBC-NEXT: sext.w a1, a1
-; RV64IMZBBC-NEXT: max a0, a1, a0
-; RV64IMZBBC-NEXT: .LBB15_2:
-; RV64IMZBBC-NEXT: ret
%minmax = call i32 @llvm.smax(i32 %x, i32 128)
%sel = select i1 %cond, i32 128, i32 %minmax
ret i32 %sel
diff --git a/llvm/test/CodeGen/RISCV/select.ll b/llvm/test/CodeGen/RISCV/select.ll
index 4a759e50b6fda..2b0206998d49b 100644
--- a/llvm/test/CodeGen/RISCV/select.ll
+++ b/llvm/test/CodeGen/RISCV/select.ll
@@ -2420,15 +2420,15 @@ define i32 @select_cst5(i1 zeroext %cond) {
;
; RV64IMXVTCONDOPS-LABEL: select_cst5:
; RV64IMXVTCONDOPS: # %bb.0:
-; RV64IMXVTCONDOPS-NEXT: xori a0, a0, 1
-; RV64IMXVTCONDOPS-NEXT: slli a0, a0, 1
+; RV64IMXVTCONDOPS-NEXT: addi a0, a0, -1
+; RV64IMXVTCONDOPS-NEXT: andi a0, a0, 2
; RV64IMXVTCONDOPS-NEXT: addi a0, a0, 2047
; RV64IMXVTCONDOPS-NEXT: ret
;
; CHECKZICOND-LABEL: select_cst5:
; CHECKZICOND: # %bb.0:
-; CHECKZICOND-NEXT: xori a0, a0, 1
-; CHECKZICOND-NEXT: slli a0, a0, 1
+; CHECKZICOND-NEXT: addi a0, a0, -1
+; CHECKZICOND-NEXT: andi a0, a0, 2
; CHECKZICOND-NEXT: addi a0, a0, 2047
; CHECKZICOND-NEXT: ret
;
@@ -2518,22 +2518,22 @@ define i32 @select_cst_diff2(i1 zeroext %cond) {
;
; RV64IMXVTCONDOPS-LABEL: select_cst_diff2:
; RV64IMXVTCONDOPS: # %bb.0:
-; RV64IMXVTCONDOPS-NEXT: xori a0, a0, 1
-; RV64IMXVTCONDOPS-NEXT: slli a0, a0, 1
+; RV64IMXVTCONDOPS-NEXT: addi a0, a0, -1
+; RV64IMXVTCONDOPS-NEXT: andi a0, a0, 2
; RV64IMXVTCONDOPS-NEXT: addiw a0, a0, 120
; RV64IMXVTCONDOPS-NEXT: ret
;
; RV32IMZICOND-LABEL: select_cst_diff2:
; RV32IMZICOND: # %bb.0:
-; RV32IMZICOND-NEXT: xori a0, a0, 1
-; RV32IMZICOND-NEXT: slli a0, a0, 1
+; RV32IMZICOND-NEXT: addi a0, a0, -1
+; RV32IMZICOND-NEXT: andi a0, a0, 2
; RV32IMZICOND-NEXT: addi a0, a0, 120
; RV32IMZICOND-NEXT: ret
;
; RV64IMZICOND-LABEL: select_cst_diff2:
; RV64IMZICOND: # %bb.0:
-; RV64IMZICOND-NEXT: xori a0, a0, 1
-; RV64IMZICOND-NEXT: slli a0, a0, 1
+; RV64IMZICOND-NEXT: addi a0, a0, -1
+; RV64IMZICOND-NEXT: andi a0, a0, 2
; RV64IMZICOND-NEXT: addiw a0, a0, 120
; RV64IMZICOND-NEXT: ret
;
@@ -2663,15 +2663,15 @@ define i32 @select_cst_diff4_invert(i1 zeroext %cond) {
;
; RV64IMXVTCONDOPS-LABEL: select_cst_diff4_invert:
; RV64IMXVTCONDOPS: # %bb.0:
-; RV64IMXVTCONDOPS-NEXT: xori a0, a0, 1
-; RV64IMXVTCONDOPS-NEXT: slli a0, a0, 2
+; RV64IMXVTCONDOPS-NEXT: addi a0, a0, -1
+; RV64IMXVTCONDOPS-NEXT: andi a0, a0, 4
; RV64IMXVTCONDOPS-NEXT: addi a0, a0, 6
; RV64IMXVTCONDOPS-NEXT: ret
;
; CHECKZICOND-LABEL: select_cst_diff4_invert:
; CHECKZICOND: # %bb.0:
-; CHECKZICOND-NEXT: xori a0, a0, 1
-; CHECKZICOND-NEXT: slli a0, a0, 2
+; CHECKZICOND-NEXT: addi a0, a0, -1
+; CHECKZICOND-NEXT: andi a0, a0, 4
; CHECKZICOND-NEXT: addi a0, a0, 6
; CHECKZICOND-NEXT: ret
;
@@ -2755,22 +2755,22 @@ define i32 @select_cst_diff8_invert(i1 zeroext %cond) {
;
; RV64IMXVTCONDOPS-LABEL: select_cst_diff8_invert:
; RV64IMXVTCONDOPS: # %bb.0:
-; RV64IMXVTCONDOPS-NEXT: xori a0, a0, 1
-; RV64IMXVTCONDOPS-NEXT: slli a0, a0, 3
+; RV64IMXVTCONDOPS-NEXT: addi a0, a0, -1
+; RV64IMXVTCONDOPS-NEXT: andi a0, a0, 8
; RV64IMXVTCONDOPS-NEXT: addiw a0, a0, 6
; RV64IMXVTCONDOPS-NEXT: ret
;
; RV32IMZICOND-LABEL: select_cst_diff8_invert:
; RV32IMZICOND: # %bb.0:
-; RV32IMZICOND-NEXT: xori a0, a0, 1
-; RV32IMZICOND-NEXT: slli a0, a0, 3
+; RV32IMZICOND-NEXT: addi a0, a0, -1
+; RV32IMZICOND-NEXT: andi a0, a0, 8
; RV32IMZICOND-NEXT: addi a0, a0, 6
; RV32IMZICOND-NEXT: ret
;
; RV64IMZICOND-LABEL: select_cst_diff8_invert:
; RV64IMZICOND: # %bb.0:
-; RV64IMZICOND-NEXT: xori a0, a0, 1
-; RV64IMZICOND-NEXT: slli a0, a0, 3
+; RV64IMZICOND-NEXT: addi a0, a0, -1
+; RV64IMZICOND-NEXT: andi a0, a0, 8
; RV64IMZICOND-NEXT: addiw a0, a0, 6
; RV64IMZICOND-NEXT: ret
;
@@ -2855,22 +2855,22 @@ define i32 @select_cst_diff1024_invert(i1 zeroext %cond) {
;
; RV64IMXVTCONDOPS-LABEL: select_cst_diff1024_invert:
; RV64IMXVTCONDOPS: # %bb.0:
-; RV64IMXVTCONDOPS-NEXT: xori a0, a0, 1
-; RV64IMXVTCONDOPS-NEXT: slli a0, a0, 10
+; RV64IMXVTCONDOPS-NEXT: addi a0, a0, -1
+; RV64IMXVTCONDOPS-NEXT: andi a0, a0, 1024
; RV64IMXVTCONDOPS-NEXT: addiw a0, a0, 6
; RV64IMXVTCONDOPS-NEXT: ret
;
; RV32IMZICOND-LABEL: select_cst_diff1024_invert:
; RV32IMZICOND: # %bb.0:
-; RV32IMZICOND-NEXT: xori a0, a0, 1
-; RV32IMZICOND-NEXT: slli a0, a0, 10
+; RV32IMZICOND-NEXT: addi a0, a0, -1
+; RV32IMZICOND-NEXT: andi a0, a0, 1024
; RV32IMZICOND-NEXT: addi a0, a0, 6
; RV32IMZICOND-NEXT: ret
;
; RV64IMZICOND-LABEL: select_cst_diff1024_invert:
; RV64IMZICOND: # %bb.0:
-; RV64IMZICOND-NEXT: xori a0, a0, 1
-; RV64IMZICOND-NEXT: slli a0, a0, 10
+; RV64IMZICOND-NEXT: addi a0, a0, -1
+; RV64IMZICOND-NEXT: andi a0, a0, 1024
; RV64IMZICOND-NEXT: addiw a0, a0, 6
; RV64IMZICOND-NEXT: ret
;
diff --git a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
index fa1807cd7d911..eadd68b0f9141 100644
--- a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
+++ b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll
@@ -109,8 +109,8 @@ define i32 @pos_sel_special_constant(i32 signext %a) {
; RV64-LABEL: pos_sel_special_constant:
; RV64: # %bb.0:
; RV64-NEXT: srli a0, a0, 63
-; RV64-NEXT: xori a0, a0, 1
-; RV64-NEXT: slli a0, a0, 9
+; RV64-NEXT: addi a0, a0, -1
+; RV64-NEXT: andi a0, a0, 512
; RV64-NEXT: ret
%tmp.1 = icmp sgt i32 %a, -1
%retval = select i1 %tmp.1, i32 512, i32 0
More information about the llvm-commits
mailing list