[llvm] [SelectionDAG] Fold saturations into min/max (PR #202067)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 6 11:23:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
@llvm/pr-subscribers-backend-systemz
Author: mike-goutokuji (mike-goutokuji)
<details>
<summary>Changes</summary>
This is similar to what we do in Instcombine.
---
Patch is 2.42 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/202067.diff
93 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+101-7)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+4-2)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-lse2.ll (+355-305)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-lse2_lse128.ll (+140-120)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-outline_atomics.ll (+355-305)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-rcpc.ll (+355-305)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-rcpc3.ll (+355-305)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-v8_1a.ll (+140-120)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-v8a.ll (+355-305)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-lse2.ll (+745-615)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-lse2_lse128.ll (+300-260)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-outline_atomics.ll (+775-645)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-rcpc.ll (+745-615)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-rcpc3.ll (+745-615)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-v8_1a.ll (+300-260)
- (modified) llvm/test/CodeGen/AArch64/Atomics/aarch64_be-atomicrmw-v8a.ll (+745-615)
- (modified) llvm/test/CodeGen/AArch64/arm64-atomic-128.ll (+28-28)
- (modified) llvm/test/CodeGen/AArch64/arm64-fmax-safe.ll (+1-2)
- (modified) llvm/test/CodeGen/AArch64/arm64-fmax.ll (+1-2)
- (modified) llvm/test/CodeGen/AArch64/atomic-ops-lse.ll (+312-312)
- (modified) llvm/test/CodeGen/AArch64/atomic-ops.ll (+88-88)
- (modified) llvm/test/CodeGen/AArch64/cond-sel.ll (+349-65)
- (modified) llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll (+148-146)
- (modified) llvm/test/CodeGen/AArch64/sat-add.ll (+15-13)
- (modified) llvm/test/CodeGen/AMDGPU/a-v-flat-atomicrmw.ll (+16-16)
- (modified) llvm/test/CodeGen/AMDGPU/flat-saddr-atomics.ll (+8-8)
- (modified) llvm/test/CodeGen/AMDGPU/flat_atomics_i64.ll (+48-48)
- (modified) llvm/test/CodeGen/AMDGPU/flat_atomics_i64_noprivate.ll (+32-32)
- (modified) llvm/test/CodeGen/AMDGPU/flat_atomics_i64_system.ll (+132-132)
- (modified) llvm/test/CodeGen/AMDGPU/flat_atomics_i64_system_noprivate.ll (+60-60)
- (modified) llvm/test/CodeGen/AMDGPU/global-saddr-atomics-min-max-system.ll (+32-32)
- (modified) llvm/test/CodeGen/AMDGPU/global_atomics_i64_system.ll (+60-60)
- (modified) llvm/test/CodeGen/AMDGPU/max.ll (+2-2)
- (modified) llvm/test/CodeGen/AMDGPU/min.ll (+81-91)
- (modified) llvm/test/CodeGen/AMDGPU/sminmax.v2i16.ll (+79-75)
- (modified) llvm/test/CodeGen/ARM/atomic-64bit.ll (+905-330)
- (modified) llvm/test/CodeGen/ARM/atomic-ops-v8.ll (+1885-896)
- (modified) llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_ints.ll (+249-280)
- (modified) llvm/test/CodeGen/ARM/atomicrmw_minmax.ll (+27-8)
- (modified) llvm/test/CodeGen/ARM/commute-movcc.ll (+5-3)
- (modified) llvm/test/CodeGen/ARM/fpclamptosat.ll (+192-193)
- (modified) llvm/test/CodeGen/ARM/fpclamptosat_vec.ll (+641-765)
- (modified) llvm/test/CodeGen/ARM/sadd_sat.ll (+132-63)
- (modified) llvm/test/CodeGen/ARM/sat-to-bitop.ll (+32-58)
- (modified) llvm/test/CodeGen/ARM/ssat.ll (+62-81)
- (modified) llvm/test/CodeGen/ARM/usat-with-shift.ll (+11-36)
- (modified) llvm/test/CodeGen/ARM/usat.ll (+81-73)
- (modified) llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-lamcas.ll (+640-680)
- (modified) llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll (+20-30)
- (modified) llvm/test/CodeGen/LoongArch/select-to-shiftand.ll (+43-29)
- (modified) llvm/test/CodeGen/NVPTX/i8x4-instructions.ll (+56-76)
- (modified) llvm/test/CodeGen/PowerPC/optcmp.ll (+2-2)
- (modified) llvm/test/CodeGen/PowerPC/sat-add.ll (+17-16)
- (modified) llvm/test/CodeGen/RISCV/atomic-rmw.ll (+1830-2130)
- (modified) llvm/test/CodeGen/RISCV/atomic-signext.ll (+397-478)
- (modified) llvm/test/CodeGen/RISCV/compress.ll (+5-4)
- (modified) llvm/test/CodeGen/RISCV/forced-atomics.ll (+61-87)
- (modified) llvm/test/CodeGen/RISCV/fpclamptosat.ll (+116-238)
- (modified) llvm/test/CodeGen/RISCV/pr148084.ll (+7-15)
- (modified) llvm/test/CodeGen/RISCV/rvv/fpclamptosat_vec.ll (+186-186)
- (modified) llvm/test/CodeGen/RISCV/select-cc.ll (+22-27)
- (modified) llvm/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll (+11-11)
- (modified) llvm/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll (+8-8)
- (modified) llvm/test/CodeGen/SystemZ/atomicrmw-ops-i128.ll (+6-6)
- (modified) llvm/test/CodeGen/SystemZ/int-max-01.ll (+20-20)
- (modified) llvm/test/CodeGen/SystemZ/int-min-01.ll (+20-20)
- (modified) llvm/test/CodeGen/Thumb2/LowOverheadLoops/minloop.ll (+14-7)
- (modified) llvm/test/CodeGen/Thumb2/mve-blockplacement.ll (+18-18)
- (modified) llvm/test/CodeGen/Thumb2/mve-vecreduce-loops.ll (+58-51)
- (modified) llvm/test/CodeGen/Thumb2/mve-vmaxv-vminv-scalar.ll (+177-68)
- (modified) llvm/test/CodeGen/Thumb2/mve-vmaxv.ll (+65-12)
- (modified) llvm/test/CodeGen/Thumb2/v8_IT_4.ll (+6-6)
- (modified) llvm/test/CodeGen/VE/Scalar/atomic.ll (+1-2)
- (modified) llvm/test/CodeGen/VE/Scalar/max.ll (+2-2)
- (modified) llvm/test/CodeGen/VE/Scalar/min.ll (+2-2)
- (modified) llvm/test/CodeGen/VE/Scalar/smin.ll (+2-2)
- (modified) llvm/test/CodeGen/WebAssembly/fpclamptosat.ll (+6-30)
- (modified) llvm/test/CodeGen/X86/8bit_cmov_of_trunc_promotion.ll (+11-11)
- (modified) llvm/test/CodeGen/X86/apx/cfcmov.ll (+4-4)
- (modified) llvm/test/CodeGen/X86/atomic-minmax-i6432.ll (+30-30)
- (modified) llvm/test/CodeGen/X86/atomic128.ll (+10-10)
- (modified) llvm/test/CodeGen/X86/atomic32.ll (+8-8)
- (modified) llvm/test/CodeGen/X86/atomic64.ll (+22-14)
- (modified) llvm/test/CodeGen/X86/atomic6432.ll (+12-12)
- (modified) llvm/test/CodeGen/X86/cmov.ll (+7-7)
- (modified) llvm/test/CodeGen/X86/fpclamptosat_vec.ll (+1050-1109)
- (modified) llvm/test/CodeGen/X86/jump_sign.ll (+20-16)
- (modified) llvm/test/CodeGen/X86/mul-constant-result.ll (+73-105)
- (modified) llvm/test/CodeGen/X86/pr5145.ll (+20-16)
- (modified) llvm/test/CodeGen/X86/sat-add.ll (+20-20)
- (modified) llvm/test/CodeGen/X86/select.ll (+19-21)
- (modified) llvm/test/CodeGen/X86/selectcc-to-shiftand.ll (+4-3)
- (modified) llvm/test/CodeGen/X86/tail-opts.ll (+2-2)
``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 7b2a35b10c318..b8c796a78b138 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -614,6 +614,9 @@ namespace {
SDValue False, ISD::CondCode CC, const SDLoc &DL);
SDValue foldSelectToUMin(SDValue LHS, SDValue RHS, SDValue True,
SDValue False, ISD::CondCode CC, const SDLoc &DL);
+ SDValue foldSelectToMinMax(const SDLoc &DL, EVT VT, SDValue LHS,
+ SDValue RHS, SDValue TrueVal, SDValue FalseVal,
+ ISD::CondCode CC);
SDValue unfoldMaskedMerge(SDNode *N);
SDValue unfoldExtremeBitClearingToShifts(SDNode *N);
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
@@ -6264,6 +6267,22 @@ static SDValue PerformUMinFpToSatCombine(SDValue N0, SDValue N1, SDValue N2,
return DAG.getZExtOrTrunc(Sat, SDLoc(N0), N3.getValueType());
}
+static bool getMinMaxOperands(SDValue Op, SDValue &X, APInt &C) {
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Op1 = Op.getOperand(1);
+ if (ConstantSDNode *C0 = isConstOrConstSplat(Op0)) {
+ X = Op1;
+ C = C0->getAPIntValue();
+ return true;
+ }
+ if (ConstantSDNode *C1 = isConstOrConstSplat(Op1)) {
+ X = Op0;
+ C = C1->getAPIntValue();
+ return true;
+ }
+ return false;
+}
+
SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -6284,6 +6303,36 @@ SDValue DAGCombiner::visitIMINMAX(SDNode *N) {
!DAG.isConstantIntBuildVectorOrConstantInt(N1))
return DAG.getNode(Opcode, DL, VT, N1, N0);
+ // Canonicalize max(min(X, HiC), LoC) -> min(max(X, LoC), HiC) when HiC > LoC.
+ // This matches InstCombine and is required for good saturation codegen on
+ // targets that lower min(max(X, 0), K) more efficiently than max(min(X, K), 0).
+ auto CanonicalizeClampForm = [&](unsigned OuterOpc, unsigned InnerOpc,
+ unsigned NewInnerOpc, unsigned NewOuterOpc,
+ auto CompareHiLo) -> SDValue {
+ if (Opcode != OuterOpc || N0.getOpcode() != InnerOpc || !N0.hasOneUse())
+ return SDValue();
+ SDValue X;
+ APInt HiC;
+ if (!getMinMaxOperands(N0, X, HiC))
+ return SDValue();
+ ConstantSDNode *LoCN = isConstOrConstSplat(N1);
+ if (!LoCN || !CompareHiLo(HiC, LoCN->getAPIntValue()))
+ return SDValue();
+ SDValue NewInner = DAG.getNode(NewInnerOpc, DL, VT, X, N1);
+ SDValue HiOp = N0.getOperand(N0.getOperand(0) == X ? 1 : 0);
+ return DAG.getNode(NewOuterOpc, DL, VT, NewInner, HiOp);
+ };
+ if (SDValue S = CanonicalizeClampForm(ISD::SMAX, ISD::SMIN, ISD::SMAX, ISD::SMIN,
+ [](const APInt &Hi, const APInt &Lo) {
+ return Hi.sgt(Lo);
+ }))
+ return S;
+ if (SDValue U = CanonicalizeClampForm(ISD::UMAX, ISD::UMIN, ISD::UMAX, ISD::UMIN,
+ [](const APInt &Hi, const APInt &Lo) {
+ return Hi.ugt(Lo);
+ }))
+ return U;
+
// fold vector ops
if (VT.isVector())
if (SDValue FoldedVOp = SimplifyVBinOp(N, DL))
@@ -12994,6 +13043,47 @@ SDValue DAGCombiner::foldSelectToUMin(SDValue LHS, SDValue RHS, SDValue True,
return SDValue();
}
+/// Fold (cmp X, Y) ? X : Y to min/max.
+SDValue DAGCombiner::foldSelectToMinMax(const SDLoc &DL, EVT VT, SDValue LHS,
+ SDValue RHS, SDValue TrueVal,
+ SDValue FalseVal, ISD::CondCode CC) {
+ if (!VT.isScalarInteger())
+ return SDValue();
+
+ if (TrueVal == RHS && FalseVal == LHS) {
+ std::swap(LHS, RHS);
+ CC = ISD::getSetCCSwappedOperands(CC);
+ }
+ if (TrueVal != LHS || FalseVal != RHS)
+ return SDValue();
+
+ unsigned Opc = 0;
+ switch (CC) {
+ case ISD::SETGT:
+ case ISD::SETGE:
+ Opc = ISD::SMAX;
+ break;
+ case ISD::SETLT:
+ case ISD::SETLE:
+ Opc = ISD::SMIN;
+ break;
+ case ISD::SETUGT:
+ case ISD::SETUGE:
+ Opc = ISD::UMAX;
+ break;
+ case ISD::SETULT:
+ case ISD::SETULE:
+ Opc = ISD::UMIN;
+ break;
+ default:
+ return SDValue();
+ }
+
+ if (!LegalOperations || hasOperation(Opc, VT))
+ return DAG.getNode(Opc, DL, VT, LHS, RHS);
+ return SDValue();
+}
+
SDValue DAGCombiner::visitSELECT(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
@@ -13121,6 +13211,9 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
SDValue Cond0 = N0.getOperand(0), Cond1 = N0.getOperand(1);
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
+ if (SDValue MinMax = foldSelectToMinMax(DL, VT, Cond0, Cond1, N1, N2, CC))
+ return MinMax;
+
// select (fcmp lt x, y), x, y -> fminnum x, y
// select (fcmp gt x, y), x, y -> fmaxnum x, y
//
@@ -14390,6 +14483,10 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) {
if (N2 == N3)
return N2;
+ if (SDValue MinMax =
+ foldSelectToMinMax(DL, N->getValueType(0), N0, N1, N2, N3, CC))
+ return MinMax;
+
// select_cc bool, 0, x, y, seteq -> select bool, y, x
if (CC == ISD::SETEQ && !LegalTypes && N0.getValueType() == MVT::i1 &&
isNullConstant(N1))
@@ -17054,9 +17151,6 @@ static SDValue detectUSatUPattern(SDValue In, EVT VT) {
/// Detect patterns of truncation with signed saturation:
/// (truncate (smin (smax (x, signed_min_of_dest_type),
/// signed_max_of_dest_type)) to dest_type)
-/// or:
-/// (truncate (smax (smin (x, signed_max_of_dest_type),
-/// signed_min_of_dest_type)) to dest_type).
///
/// Return the source value to be truncated or SDValue() if the pattern was not
/// matched.
@@ -17092,14 +17186,14 @@ static SDValue detectSSatUPattern(SDValue In, EVT VT, SelectionDAG &DAG,
SDValue Val;
APInt UnsignedMax = APInt::getMaxValue(NumDstBits).zext(NumSrcBits);
// Min == 0, Max is unsigned max of destination type.
- if (sd_match(In, m_SMax(m_SMin(m_Value(Val), m_SpecificInt(UnsignedMax)),
- m_Zero())))
- return Val;
-
if (sd_match(In, m_SMin(m_SMax(m_Value(Val), m_Zero()),
m_SpecificInt(UnsignedMax))))
return Val;
+ if (sd_match(In, m_SMax(m_SMin(m_Value(Val), m_SpecificInt(UnsignedMax)),
+ m_Zero())))
+ return Val;
+
if (sd_match(In, m_UMin(m_SMax(m_Value(Val), m_Zero()),
m_SpecificInt(UnsignedMax))))
return Val;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index e08a4f5ebda08..b05a48be026d1 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -18085,7 +18085,8 @@ static SDValue PerformMinMaxToSatCombine(SDValue Op, SelectionDAG &DAG,
SDValue Op0 = Op.getOperand(0);
if (VT != MVT::i32 ||
- (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX) ||
+ (Op0.getOpcode() != ISD::SMIN && Op0.getOpcode() != ISD::SMAX &&
+ Op0.getOpcode() != ISD::UMIN) ||
!isa<ConstantSDNode>(Op.getOperand(1)) ||
!isa<ConstantSDNode>(Op0.getOperand(1)))
return SDValue();
@@ -18099,7 +18100,8 @@ static SDValue PerformMinMaxToSatCombine(SDValue Op, SelectionDAG &DAG,
APInt MinC = Min.getConstantOperandAPInt(1);
APInt MaxC = Max.getConstantOperandAPInt(1);
- if (Min.getOpcode() != ISD::SMIN || Max.getOpcode() != ISD::SMAX ||
+ if ((Min.getOpcode() != ISD::SMIN && Min.getOpcode() != ISD::UMIN) ||
+ Max.getOpcode() != ISD::SMAX ||
!(MinC + 1).isPowerOf2())
return SDValue();
diff --git a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-lse2.ll b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-lse2.ll
index dfce1fbe0d30f..880f3d5d4220b 100644
--- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-lse2.ll
+++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomicrmw-lse2.ll
@@ -5345,11 +5345,12 @@ define dso_local i8 @atomicrmw_max_i8_aligned_monotonic(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_aligned_monotonic:
-; -O1: ldxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value monotonic, align 1
ret i8 %r
}
@@ -5366,11 +5367,12 @@ define dso_local i8 @atomicrmw_max_i8_aligned_acquire(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_aligned_acquire:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value acquire, align 1
ret i8 %r
}
@@ -5387,11 +5389,12 @@ define dso_local i8 @atomicrmw_max_i8_aligned_release(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_aligned_release:
-; -O1: ldxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value release, align 1
ret i8 %r
}
@@ -5408,11 +5411,12 @@ define dso_local i8 @atomicrmw_max_i8_aligned_acq_rel(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_aligned_acq_rel:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value acq_rel, align 1
ret i8 %r
}
@@ -5429,11 +5433,12 @@ define dso_local i8 @atomicrmw_max_i8_aligned_seq_cst(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_aligned_seq_cst:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value seq_cst, align 1
ret i8 %r
}
@@ -5449,11 +5454,12 @@ define dso_local i16 @atomicrmw_max_i16_aligned_monotonic(ptr %ptr, i16 %value)
; -O0: subs w9, w9, w10, uxth
;
; -O1-LABEL: atomicrmw_max_i16_aligned_monotonic:
-; -O1: ldxrh w9, [x0]
-; -O1: sxth w8, w9
-; -O1: cmp w8, w1, sxth
-; -O1: csel w9, w9, w1, gt
-; -O1: stxrh w10, w9, [x0]
+; -O1: sxth w9, w1
+; -O1: ldxrh w8, [x0]
+; -O1: sxth w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stxrh w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i16 %value monotonic, align 2
ret i16 %r
}
@@ -5469,11 +5475,12 @@ define dso_local i16 @atomicrmw_max_i16_aligned_acquire(ptr %ptr, i16 %value) {
; -O0: subs w9, w9, w10, uxth
;
; -O1-LABEL: atomicrmw_max_i16_aligned_acquire:
-; -O1: ldaxrh w9, [x0]
-; -O1: sxth w8, w9
-; -O1: cmp w8, w1, sxth
-; -O1: csel w9, w9, w1, gt
-; -O1: stxrh w10, w9, [x0]
+; -O1: sxth w9, w1
+; -O1: ldaxrh w8, [x0]
+; -O1: sxth w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stxrh w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i16 %value acquire, align 2
ret i16 %r
}
@@ -5489,11 +5496,12 @@ define dso_local i16 @atomicrmw_max_i16_aligned_release(ptr %ptr, i16 %value) {
; -O0: subs w9, w9, w10, uxth
;
; -O1-LABEL: atomicrmw_max_i16_aligned_release:
-; -O1: ldxrh w9, [x0]
-; -O1: sxth w8, w9
-; -O1: cmp w8, w1, sxth
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrh w10, w9, [x0]
+; -O1: sxth w9, w1
+; -O1: ldxrh w8, [x0]
+; -O1: sxth w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrh w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i16 %value release, align 2
ret i16 %r
}
@@ -5509,11 +5517,12 @@ define dso_local i16 @atomicrmw_max_i16_aligned_acq_rel(ptr %ptr, i16 %value) {
; -O0: subs w9, w9, w10, uxth
;
; -O1-LABEL: atomicrmw_max_i16_aligned_acq_rel:
-; -O1: ldaxrh w9, [x0]
-; -O1: sxth w8, w9
-; -O1: cmp w8, w1, sxth
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrh w10, w9, [x0]
+; -O1: sxth w9, w1
+; -O1: ldaxrh w8, [x0]
+; -O1: sxth w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrh w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i16 %value acq_rel, align 2
ret i16 %r
}
@@ -5529,11 +5538,12 @@ define dso_local i16 @atomicrmw_max_i16_aligned_seq_cst(ptr %ptr, i16 %value) {
; -O0: subs w9, w9, w10, uxth
;
; -O1-LABEL: atomicrmw_max_i16_aligned_seq_cst:
-; -O1: ldaxrh w9, [x0]
-; -O1: sxth w8, w9
-; -O1: cmp w8, w1, sxth
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrh w10, w9, [x0]
+; -O1: sxth w9, w1
+; -O1: ldaxrh w8, [x0]
+; -O1: sxth w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrh w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i16 %value seq_cst, align 2
ret i16 %r
}
@@ -5875,11 +5885,12 @@ define dso_local i8 @atomicrmw_max_i8_unaligned_monotonic(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_unaligned_monotonic:
-; -O1: ldxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value monotonic, align 1
ret i8 %r
}
@@ -5896,11 +5907,12 @@ define dso_local i8 @atomicrmw_max_i8_unaligned_acquire(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_unaligned_acquire:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value acquire, align 1
ret i8 %r
}
@@ -5917,11 +5929,12 @@ define dso_local i8 @atomicrmw_max_i8_unaligned_release(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_unaligned_release:
-; -O1: ldxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value release, align 1
ret i8 %r
}
@@ -5938,11 +5951,12 @@ define dso_local i8 @atomicrmw_max_i8_unaligned_acq_rel(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_unaligned_acq_rel:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value acq_rel, align 1
ret i8 %r
}
@@ -5959,11 +5973,12 @@ define dso_local i8 @atomicrmw_max_i8_unaligned_seq_cst(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_max_i8_unaligned_seq_cst:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, gt
-; -O1: stlxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, gt
+; -O1: stlxrb w11, w10, [x0]
%r = atomicrmw max ptr %ptr, i8 %value seq_cst, align 1
ret i8 %r
}
@@ -5976,9 +5991,10 @@ define dso_local i16 @atomicrmw_max_i16_unaligned_monotonic(ptr %ptr, i16 %value
; -O0: bl __atomic_compare_exchange
;
; -O1-LABEL: atomicrmw_max_i16_unaligned_monotonic:
+; -O1: sxth w20, w1
; -O1: sxth w8, w0
-; -O1: cmp w8, w20, sxth
-; -O1: csel w8, w0, w20, gt
+; -O1: cmp w8, w20
+; -O1: csel w8, w8, w20, gt
; -O1: bl __atomic_compare_exchange
%r = atomicrmw max ptr %ptr, i16 %value monotonic, align 1
ret i16 %r
@@ -5992,9 +6008,10 @@ define dso_local i16 @atomicrmw_max_i16_unaligned_acquire(ptr %ptr, i16 %value)
; -O0: bl __atomic_compare_exchange
;
; -O1-LABEL: atomicrmw_max_i16_unaligned_acquire:
+; -O1: sxth w20, w1
; -O1: sxth w8, w0
-; -O1: cmp w8, w20, sxth
-; -O1: csel w8, w0, w20, gt
+; -O1: cmp w8, w20
+; -O1: csel w8, w8, w20, gt
; -O1: bl __atomic_compare_exchange
%r = atomicrmw max ptr %ptr, i16 %value acquire, align 1
ret i16 %r
@@ -6008,9 +6025,10 @@ define dso_local i16 @atomicrmw_max_i16_unaligned_release(ptr %ptr, i16 %value)
; -O0: bl __atomic_compare_exchange
;
; -O1-LABEL: atomicrmw_max_i16_unaligned_release:
+; -O1: sxth w20, w1
; -O1: sxth w8, w0
-; -O1: cmp w8, w20, sxth
-; -O1: csel w8, w0, w20, gt
+; -O1: cmp w8, w20
+; -O1: csel w8, w8, w20, gt
; -O1: bl __atomic_compare_exchange
%r = atomicrmw max ptr %ptr, i16 %value release, align 1
ret i16 %r
@@ -6024,9 +6042,10 @@ define dso_local i16 @atomicrmw_max_i16_unaligned_acq_rel(ptr %ptr, i16 %value)
; -O0: bl __atomic_compare_exchange
;
; -O1-LABEL: atomicrmw_max_i16_unaligned_acq_rel:
+; -O1: sxth w20, w1
; -O1: sxth w8, w0
-; -O1: cmp w8, w20, sxth
-; -O1: csel w8, w0, w20, gt
+; -O1: cmp w8, w20
+; -O1: csel w8, w8, w20, gt
; -O1: bl __atomic_compare_exchange
%r = atomicrmw max ptr %ptr, i16 %value acq_rel, align 1
ret i16 %r
@@ -6040,9 +6059,10 @@ define dso_local i16 @atomicrmw_max_i16_unaligned_seq_cst(ptr %ptr, i16 %value)
; -O0: bl __atomic_compare_exchange
;
; -O1-LABEL: atomicrmw_max_i16_unaligned_seq_cst:
+; -O1: sxth w20, w1
; -O1: sxth w8, w0
-; -O1: cmp w8, w20, sxth
-; -O1: csel w8, w0, w20, gt
+; -O1: cmp w8, w20
+; -O1: csel w8, w8, w20, gt
; -O1: bl __atomic_compare_exchange
%r = atomicrmw max ptr %ptr, i16 %value seq_cst, align 1
ret i16 %r
@@ -6310,11 +6330,12 @@ define dso_local i8 @atomicrmw_min_i8_aligned_monotonic(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_min_i8_aligned_monotonic:
-; -O1: ldxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, le
-; -O1: stxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, lt
+; -O1: stxrb w11, w10, [x0]
%r = atomicrmw min ptr %ptr, i8 %value monotonic, align 1
ret i8 %r
}
@@ -6331,11 +6352,12 @@ define dso_local i8 @atomicrmw_min_i8_aligned_acquire(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_min_i8_aligned_acquire:
-; -O1: ldaxrb w9, [x0]
-; -O1: sxtb w8, w9
-; -O1: cmp w8, w1, sxtb
-; -O1: csel w9, w9, w1, le
-; -O1: stxrb w10, w9, [x0]
+; -O1: sxtb w9, w1
+; -O1: ldaxrb w8, [x0]
+; -O1: sxtb w8, w8
+; -O1: cmp w8, w9
+; -O1: csel w10, w8, w9, lt
+; -O1: stxrb w11, w10, [x0]
%r = atomicrmw min ptr %ptr, i8 %value acquire, align 1
ret i8 %r
}
@@ -6352,11 +6374,12 @@ define dso_local i8 @atomicrmw_min_i8_aligned_release(ptr %ptr, i8 %value) {
; -O0: subs w9, w9, w10, uxtb
;
; -O1-LABEL: atomicrmw_min_i8_aligned_release:
-; -O1: ldxrb w9, [x0]
-; -...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/202067
More information about the llvm-commits
mailing list