[clang] [llvm] [RISCV][LLVM] Enable atomics for 'Zalrsc' (PR #163672)

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 15 23:05:39 PDT 2025


================
@@ -29572,6 +36161,22 @@ define i32 @atomicrmw_umax_i32_monotonic(ptr %a, i32 %b) nounwind {
 ; RV64I-NEXT:    addi sp, sp, 48
 ; RV64I-NEXT:    ret
 ;
+; RV64I-ZALRSC-LABEL: atomicrmw_umax_i32_monotonic:
+; RV64I-ZALRSC:       # %bb.0:
+; RV64I-ZALRSC-NEXT:  .LBB175_1: # =>This Inner Loop Header: Depth=1
+; RV64I-ZALRSC-NEXT:    lr.w a2, (a0)
+; RV64I-ZALRSC-NEXT:    slli a3, a2, 32
+; RV64I-ZALRSC-NEXT:    srli a3, a3, 32
+; RV64I-ZALRSC-NEXT:    bgeu a3, a1, .LBB175_3
----------------
slachowsky wrote:

This is unfortunate.

The type legalizer is handling the 32-bit arguments properly for the `cmpxchg` case because TLI.getExtendForAtomicCmpSwapArg() controls the argument promotion in DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap(), and RISCV TLI overrides this virtual to return SIGN_EXTEND for correct behavior.

No such control was plumbed for DAGTypeLegalizer::PromoteIntRes_Atomic1() used for `atomicrmw <op>` cases, so we get any extended arguments always.

We could add another virtual TLI function to control this more explicitly for anyone else that might want it.

Or some early RISCV DAGCombine to adjust `atomicrmw {min,max,umin,umax}`  arguments and avoid the default legalizer behavior.

Or solve this in the pseudo expansion, but that is not ideal because I believe it would require a second scratch register.

Thoughts?

https://github.com/llvm/llvm-project/pull/163672


More information about the cfe-commits mailing list