[llvm] [DAG] Convert select of constants to arithmetic operations (PR #198951)

dong jianqiang via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 14 01:58:16 PDT 2026


https://github.com/dongjianqiang2 updated https://github.com/llvm/llvm-project/pull/198951

>From c4c09b9ca6458eb3ce11cb1c2f51fbbd916af83b Mon Sep 17 00:00:00 2001
From: Dong JianQiang <dongjianqiang2 at huawei.com>
Date: Fri, 12 Jun 2026 18:39:28 +0800
Subject: [PATCH] [DAG] Add select Cond, 0, Pow2 fold and RISCV reverse combine

Add the missing unconditional fold `select Cond, 0, Pow2 -> (zext (!Cond))
<< log2(Pow2)` in foldSelectOfConstants, filling the gap alongside the
existing 0/1, 1/0, 0/-1 and -1/0 unconditional folds.

On RISCV the generic fold can regress code size under the C/Zca extension
because `xori 1` never compresses, while the original select lowering
produces the compressible `addi -1; andi Pow2`.  Add a target-specific
post-legalize combine that reverses the fold when the condition is an i1
function argument (identified by AssertZext), converting `shl (xor
(assertzext Cond, i1), 1), C` back to `select Cond, 0, 1<<C`.

Fixes #196488
---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  9 +++
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   | 27 ++++++++-
 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 ++--
 llvm/test/CodeGen/ARM/select_const.ll         | 27 +++++++++
 .../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-const.ll       |  8 +--
 llvm/test/CodeGen/RISCV/select.ll             | 52 ++++++++--------
 llvm/test/CodeGen/Thumb/branchless-cmp.ll     | 18 +++---
 19 files changed, 185 insertions(+), 148 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 4953a9add0df6..a926d74626c60 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12753,6 +12753,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/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 57af056c2d3c0..9826b7c57876b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1923,7 +1923,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())
@@ -1952,7 +1952,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
                          ISD::VP_GATHER,
                          ISD::VP_SCATTER,
                          ISD::SRL,
-                         ISD::SHL,
                          ISD::STORE,
                          ISD::SPLAT_VECTOR,
                          ISD::BUILD_VECTOR,
@@ -21261,6 +21260,29 @@ static SDValue performSHLCombine(SDNode *N,
   if (SDValue V = combineOp_VLToVWOp_VL(N, DCI, Subtarget))
     return V;
 
+  SelectionDAG &DAG = DCI.DAG;
+
+  // Reverse the generic fold for select Cond, 0, Pow2: when Cond is an i1
+  // function argument promoted via AssertZext, prefer the select lowering
+  // (addi -1; andi Pow2) over the generic xori 1; slli C, because the former
+  // is two RVC-compressible instructions for small Pow2.
+  if (DCI.isAfterLegalizeDAG()) {
+    using namespace SDPatternMatch;
+    EVT VT = N->getValueType(0);
+    SDValue X;
+    uint64_t ShAmtVal;
+    if (!VT.isVector() &&
+        sd_match(N, m_Shl(m_OneUse(m_Xor(m_Value(X), m_One())),
+                          m_ConstInt(ShAmtVal))) &&
+        X.getOpcode() == ISD::AssertZext &&
+        cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i1) {
+      SDLoc DL(N);
+      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));
+    }
+  }
+
   // (shl (sext x), C) -> (vwmulsu x, 1u << C)
   // (shl (zext x), C) -> (vwmulu  x, 1u << C)
 
@@ -21310,7 +21332,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/AArch64/arm64-csel.ll b/llvm/test/CodeGen/AArch64/arm64-csel.ll
index ecdcbfe226e40..e152015c2a85e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-csel.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-csel.ll
@@ -399,9 +399,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 a39d3fb10a2fa..7780fb0354f31 100644
--- a/llvm/test/CodeGen/AMDGPU/sdiv64.ll
+++ b/llvm/test/CodeGen/AMDGPU/sdiv64.ll
@@ -1759,15 +1759,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 f3fdfaadc86ab..c4aeab72b54eb 100644
--- a/llvm/test/CodeGen/AMDGPU/srem64.ll
+++ b/llvm/test/CodeGen/AMDGPU/srem64.ll
@@ -1845,14 +1845,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 97e0937760f92..cc48edf395ae7 100644
--- a/llvm/test/CodeGen/AMDGPU/udiv64.ll
+++ b/llvm/test/CodeGen/AMDGPU/udiv64.ll
@@ -1177,14 +1177,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 0952013401892..d0e56e155f984 100644
--- a/llvm/test/CodeGen/AMDGPU/urem64.ll
+++ b/llvm/test/CodeGen/AMDGPU/urem64.ll
@@ -1253,14 +1253,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/ARM/select_const.ll b/llvm/test/CodeGen/ARM/select_const.ll
index 77b67cc40f707..63bef887ada14 100644
--- a/llvm/test/CodeGen/ARM/select_const.ll
+++ b/llvm/test/CodeGen/ARM/select_const.ll
@@ -802,3 +802,30 @@ entry:
   %2 = select i1 %1, i64 8, i64 0
   ret i64 %2
 }
+
+; select Cond, 0, Pow2 --> (zext (!Cond)) << log2(Pow2)
+
+define i32 @select_0_or_16(i1 %cond) {
+; ARM-LABEL: select_0_or_16:
+; ARM:       @ %bb.0:
+; ARM-NEXT:    mov r1, #1
+; ARM-NEXT:    bic r0, r1, r0
+; ARM-NEXT:    lsl r0, r0, #4
+; ARM-NEXT:    mov pc, lr
+;
+; THUMB2-LABEL: select_0_or_16:
+; THUMB2:       @ %bb.0:
+; THUMB2-NEXT:    movs r1, #1
+; THUMB2-NEXT:    bic.w r0, r1, r0
+; THUMB2-NEXT:    lsls r0, r0, #4
+; THUMB2-NEXT:    bx lr
+;
+; THUMB-LABEL: select_0_or_16:
+; THUMB:       @ %bb.0:
+; THUMB-NEXT:    mvns r0, r0
+; THUMB-NEXT:    lsls r0, r0, #31
+; THUMB-NEXT:    lsrs r0, r0, #27
+; THUMB-NEXT:    bx lr
+  %sel = select i1 %cond, i32 0, i32 16
+  ret i32 %sel
+}
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-const.ll b/llvm/test/CodeGen/RISCV/select-const.ll
index 3ef5ddb032554..43ee831018cad 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
diff --git a/llvm/test/CodeGen/RISCV/select.ll b/llvm/test/CodeGen/RISCV/select.ll
index 00327b8b3f713..f57429d296046 100644
--- a/llvm/test/CodeGen/RISCV/select.ll
+++ b/llvm/test/CodeGen/RISCV/select.ll
@@ -2428,15 +2428,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
 ;
@@ -2526,22 +2526,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
 ;
@@ -2671,15 +2671,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
 ;
@@ -2763,22 +2763,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
 ;
@@ -2863,22 +2863,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/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



More information about the llvm-commits mailing list