[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