[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