[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