[RISCV][GlobalISel] Legalize G_ATOMICRMW_MAX/MIN/UMAX/UMIN (#210891)

Add a legalizer rule that marks these legal at `sXLen` under `+a`
(selecting `amomax.w/d`, and `amomax.b/h` for sub-word under `+zabha`
via the existing widen-scalar-while-preserving-the-memoperand path), and
handle the `llvm.riscv.masked.atomicrmw.{max,min,umax,umin}` intrinsics
the same way as `add/sub/xchg` so sub-word values without `+zabha` use
the LR/SC masking pseudos. There is no `__atomic_fetch_max/min` libcall,
so unlike `add/and/or/xor` the rule does not libcall the no-A case; that
case is already lowered by an IR-level compare-exchange loop and never
reaches GlobalISel, so the rule marks it unsupported to keep the rule
set well-defined.

Updates `legalizer-info-validation.mir` for the newly defined rules and
adds `atomicrmw-max-min-umax-umin.ll`.
This commit is contained in:
Kane Wang 2026-07-22 09:16:35 +08:00 committed by GitHub
parent 14bfc424ae
commit 373df745fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 13089 additions and 8 deletions

View file

@ -748,6 +748,12 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.clampScalar(0, sXLen, sXLen)
.lower();
getActionDefinitionsBuilder(
{G_ATOMICRMW_MAX, G_ATOMICRMW_MIN, G_ATOMICRMW_UMAX, G_ATOMICRMW_UMIN})
.legalFor(ST.hasStdExtA(), {{sXLen, p0}})
.clampScalar(0, sXLen, sXLen)
.unsupported();
LegalityPredicate InsertVectorEltPred = [=](const LegalityQuery &Query) {
LLT VecTy = Query.Types[0];
LLT EltTy = Query.Types[1];
@ -833,6 +839,10 @@ bool RISCVLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
case Intrinsic::riscv_masked_atomicrmw_add:
case Intrinsic::riscv_masked_atomicrmw_sub:
case Intrinsic::riscv_masked_atomicrmw_xchg:
case Intrinsic::riscv_masked_atomicrmw_max:
case Intrinsic::riscv_masked_atomicrmw_min:
case Intrinsic::riscv_masked_atomicrmw_umax:
case Intrinsic::riscv_masked_atomicrmw_umin:
case Intrinsic::riscv_masked_cmpxchg:
return true;
}

File diff suppressed because it is too large Load diff

View file

@ -267,17 +267,20 @@
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_ATOMICRMW_MAX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_ATOMICRMW_MIN (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_ATOMICRMW_UMAX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_ATOMICRMW_UMIN (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_ATOMICRMW_FADD (opcode {{[0-9]+}}): 2 type indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined