[llvm] [RISCV][GlobalISel] Legalize G_ATOMICRMW_XCHG (PR #209983)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 23:46:54 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Kane Wang (ReVe1uv)
<details>
<summary>Changes</summary>
This commit makes `xchg` consistent with `add/and/or/xor` across all type/extension combinations. Updates `legalizer-info-validation.mir` for the newly defined rules and adds `atomicrmw-xchg.ll` and `legalize-atomicrmw-xchg-rv{32,64}.mir` tests.
---
Patch is 54.96 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/209983.diff
5 Files Affected:
- (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+3-2)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/atomicrmw-xchg.ll (+1267)
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir (+3-2)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-atomicrmw-xchg-rv32.mir (+94)
- (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-atomicrmw-xchg-rv64.mir (+125)
``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 6acb66c449dd8..8f1ac4509425d 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -737,8 +737,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
.lowerIf(all(typeInSet(0, {s8, s16, s32, s64}), typeIs(2, p0)));
getActionDefinitionsBuilder({G_ATOMIC_CMPXCHG, G_ATOMICRMW_ADD,
- G_ATOMICRMW_AND, G_ATOMICRMW_OR,
- G_ATOMICRMW_XOR})
+ G_ATOMICRMW_XCHG, G_ATOMICRMW_AND,
+ G_ATOMICRMW_OR, G_ATOMICRMW_XOR})
.legalFor(ST.hasStdExtA(), {{sXLen, p0}})
.libcallFor(!ST.hasStdExtA(), {{s8, p0}, {s16, p0}, {s32, p0}, {s64, p0}})
.clampScalar(0, sXLen, sXLen);
@@ -832,6 +832,7 @@ bool RISCVLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
case Intrinsic::riscv_vsetvlimax:
case Intrinsic::riscv_masked_atomicrmw_add:
case Intrinsic::riscv_masked_atomicrmw_sub:
+ case Intrinsic::riscv_masked_atomicrmw_xchg:
case Intrinsic::riscv_masked_cmpxchg:
return true;
}
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/atomicrmw-xchg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/atomicrmw-xchg.ll
new file mode 100644
index 0000000000000..909146854b33e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/atomicrmw-xchg.ll
@@ -0,0 +1,1267 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -global-isel -mtriple=riscv32 -mattr=+a,+zabha < %s | FileCheck %s --check-prefixes=RV32IA-ZABHA
+; RUN: llc -global-isel -mtriple=riscv32 -mattr=+a < %s | FileCheck %s --check-prefixes=RV32IA
+; RUN: llc -global-isel -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=RV32I
+; RUN: llc -global-isel -mtriple=riscv64 -mattr=+a,+zabha < %s | FileCheck %s --check-prefixes=RV64IA-ZABHA
+; RUN: llc -global-isel -mtriple=riscv64 -mattr=+a < %s | FileCheck %s --check-prefixes=RV64IA
+; RUN: llc -global-isel -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=RV64I
+
+define i8 @atomicrmw_xchg_i8_monotonic(ptr %ptr, i8 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i8_monotonic:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.b a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i8_monotonic:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: li a2, 255
+; RV32IA-NEXT: andi a3, a0, -4
+; RV32IA-NEXT: andi a0, a0, 3
+; RV32IA-NEXT: slli a0, a0, 3
+; RV32IA-NEXT: zext.b a1, a1
+; RV32IA-NEXT: sll a2, a2, a0
+; RV32IA-NEXT: sll a1, a1, a0
+; RV32IA-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; RV32IA-NEXT: lr.w a4, (a3)
+; RV32IA-NEXT: mv a5, a1
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: and a5, a5, a2
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: sc.w a5, a5, (a3)
+; RV32IA-NEXT: bnez a5, .LBB0_1
+; RV32IA-NEXT: # %bb.2:
+; RV32IA-NEXT: srl a0, a4, a0
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i8_monotonic:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 0
+; RV32I-NEXT: call __atomic_exchange_1
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i8_monotonic:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.b a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i8_monotonic:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: li a2, 255
+; RV64IA-NEXT: andi a3, a0, -4
+; RV64IA-NEXT: andi a0, a0, 3
+; RV64IA-NEXT: slli a0, a0, 3
+; RV64IA-NEXT: zext.b a1, a1
+; RV64IA-NEXT: sllw a2, a2, a0
+; RV64IA-NEXT: sllw a1, a1, a0
+; RV64IA-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; RV64IA-NEXT: lr.w a4, (a3)
+; RV64IA-NEXT: mv a5, a1
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: and a5, a5, a2
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: sc.w a5, a5, (a3)
+; RV64IA-NEXT: bnez a5, .LBB0_1
+; RV64IA-NEXT: # %bb.2:
+; RV64IA-NEXT: srlw a0, a4, a0
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i8_monotonic:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 0
+; RV64I-NEXT: call __atomic_exchange_1
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i8 %val monotonic
+ ret i8 %res
+}
+
+define i16 @atomicrmw_xchg_i16_monotonic(ptr %ptr, i16 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i16_monotonic:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.h a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i16_monotonic:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: lui a2, 16
+; RV32IA-NEXT: addi a2, a2, -1
+; RV32IA-NEXT: andi a3, a0, -4
+; RV32IA-NEXT: andi a0, a0, 3
+; RV32IA-NEXT: slli a0, a0, 3
+; RV32IA-NEXT: and a1, a1, a2
+; RV32IA-NEXT: sll a2, a2, a0
+; RV32IA-NEXT: sll a1, a1, a0
+; RV32IA-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
+; RV32IA-NEXT: lr.w a4, (a3)
+; RV32IA-NEXT: mv a5, a1
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: and a5, a5, a2
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: sc.w a5, a5, (a3)
+; RV32IA-NEXT: bnez a5, .LBB1_1
+; RV32IA-NEXT: # %bb.2:
+; RV32IA-NEXT: srl a0, a4, a0
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i16_monotonic:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 0
+; RV32I-NEXT: call __atomic_exchange_2
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i16_monotonic:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.h a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i16_monotonic:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: lui a2, 16
+; RV64IA-NEXT: addi a2, a2, -1
+; RV64IA-NEXT: andi a3, a0, -4
+; RV64IA-NEXT: andi a0, a0, 3
+; RV64IA-NEXT: slli a0, a0, 3
+; RV64IA-NEXT: and a1, a1, a2
+; RV64IA-NEXT: sllw a2, a2, a0
+; RV64IA-NEXT: sllw a1, a1, a0
+; RV64IA-NEXT: .LBB1_1: # =>This Inner Loop Header: Depth=1
+; RV64IA-NEXT: lr.w a4, (a3)
+; RV64IA-NEXT: mv a5, a1
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: and a5, a5, a2
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: sc.w a5, a5, (a3)
+; RV64IA-NEXT: bnez a5, .LBB1_1
+; RV64IA-NEXT: # %bb.2:
+; RV64IA-NEXT: srlw a0, a4, a0
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i16_monotonic:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 0
+; RV64I-NEXT: call __atomic_exchange_2
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i16 %val monotonic
+ ret i16 %res
+}
+
+define i32 @atomicrmw_xchg_i32_monotonic(ptr %ptr, i32 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i32_monotonic:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.w a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i32_monotonic:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: amoswap.w a0, a1, (a0)
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i32_monotonic:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 0
+; RV32I-NEXT: call __atomic_exchange_4
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i32_monotonic:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.w a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i32_monotonic:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: amoswap.w a0, a1, (a0)
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i32_monotonic:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 0
+; RV64I-NEXT: call __atomic_exchange_4
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i32 %val monotonic
+ ret i32 %res
+}
+
+define i64 @atomicrmw_xchg_i64_monotonic(ptr %ptr, i64 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i64_monotonic:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: addi sp, sp, -16
+; RV32IA-ZABHA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IA-ZABHA-NEXT: li a3, 0
+; RV32IA-ZABHA-NEXT: call __atomic_exchange_8
+; RV32IA-ZABHA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IA-ZABHA-NEXT: addi sp, sp, 16
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i64_monotonic:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: addi sp, sp, -16
+; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IA-NEXT: li a3, 0
+; RV32IA-NEXT: call __atomic_exchange_8
+; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IA-NEXT: addi sp, sp, 16
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i64_monotonic:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a3, 0
+; RV32I-NEXT: call __atomic_exchange_8
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i64_monotonic:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.d a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i64_monotonic:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: amoswap.d a0, a1, (a0)
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i64_monotonic:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 0
+; RV64I-NEXT: call __atomic_exchange_8
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i64 %val monotonic
+ ret i64 %res
+}
+
+define i8 @atomicrmw_xchg_i8_acquire(ptr %ptr, i8 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i8_acquire:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.b.aq a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i8_acquire:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: li a2, 255
+; RV32IA-NEXT: andi a3, a0, -4
+; RV32IA-NEXT: andi a0, a0, 3
+; RV32IA-NEXT: slli a0, a0, 3
+; RV32IA-NEXT: zext.b a1, a1
+; RV32IA-NEXT: sll a2, a2, a0
+; RV32IA-NEXT: sll a1, a1, a0
+; RV32IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1
+; RV32IA-NEXT: lr.w.aq a4, (a3)
+; RV32IA-NEXT: mv a5, a1
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: and a5, a5, a2
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: sc.w a5, a5, (a3)
+; RV32IA-NEXT: bnez a5, .LBB4_1
+; RV32IA-NEXT: # %bb.2:
+; RV32IA-NEXT: srl a0, a4, a0
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i8_acquire:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 2
+; RV32I-NEXT: call __atomic_exchange_1
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i8_acquire:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.b.aq a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i8_acquire:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: li a2, 255
+; RV64IA-NEXT: andi a3, a0, -4
+; RV64IA-NEXT: andi a0, a0, 3
+; RV64IA-NEXT: slli a0, a0, 3
+; RV64IA-NEXT: zext.b a1, a1
+; RV64IA-NEXT: sllw a2, a2, a0
+; RV64IA-NEXT: sllw a1, a1, a0
+; RV64IA-NEXT: .LBB4_1: # =>This Inner Loop Header: Depth=1
+; RV64IA-NEXT: lr.w.aq a4, (a3)
+; RV64IA-NEXT: mv a5, a1
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: and a5, a5, a2
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: sc.w a5, a5, (a3)
+; RV64IA-NEXT: bnez a5, .LBB4_1
+; RV64IA-NEXT: # %bb.2:
+; RV64IA-NEXT: srlw a0, a4, a0
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i8_acquire:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 2
+; RV64I-NEXT: call __atomic_exchange_1
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i8 %val acquire
+ ret i8 %res
+}
+
+define i16 @atomicrmw_xchg_i16_acquire(ptr %ptr, i16 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i16_acquire:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.h.aq a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i16_acquire:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: lui a2, 16
+; RV32IA-NEXT: addi a2, a2, -1
+; RV32IA-NEXT: andi a3, a0, -4
+; RV32IA-NEXT: andi a0, a0, 3
+; RV32IA-NEXT: slli a0, a0, 3
+; RV32IA-NEXT: and a1, a1, a2
+; RV32IA-NEXT: sll a2, a2, a0
+; RV32IA-NEXT: sll a1, a1, a0
+; RV32IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1
+; RV32IA-NEXT: lr.w.aq a4, (a3)
+; RV32IA-NEXT: mv a5, a1
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: and a5, a5, a2
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: sc.w a5, a5, (a3)
+; RV32IA-NEXT: bnez a5, .LBB5_1
+; RV32IA-NEXT: # %bb.2:
+; RV32IA-NEXT: srl a0, a4, a0
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i16_acquire:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 2
+; RV32I-NEXT: call __atomic_exchange_2
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i16_acquire:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.h.aq a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i16_acquire:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: lui a2, 16
+; RV64IA-NEXT: addi a2, a2, -1
+; RV64IA-NEXT: andi a3, a0, -4
+; RV64IA-NEXT: andi a0, a0, 3
+; RV64IA-NEXT: slli a0, a0, 3
+; RV64IA-NEXT: and a1, a1, a2
+; RV64IA-NEXT: sllw a2, a2, a0
+; RV64IA-NEXT: sllw a1, a1, a0
+; RV64IA-NEXT: .LBB5_1: # =>This Inner Loop Header: Depth=1
+; RV64IA-NEXT: lr.w.aq a4, (a3)
+; RV64IA-NEXT: mv a5, a1
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: and a5, a5, a2
+; RV64IA-NEXT: xor a5, a4, a5
+; RV64IA-NEXT: sc.w a5, a5, (a3)
+; RV64IA-NEXT: bnez a5, .LBB5_1
+; RV64IA-NEXT: # %bb.2:
+; RV64IA-NEXT: srlw a0, a4, a0
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i16_acquire:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 2
+; RV64I-NEXT: call __atomic_exchange_2
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i16 %val acquire
+ ret i16 %res
+}
+
+define i32 @atomicrmw_xchg_i32_acquire(ptr %ptr, i32 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i32_acquire:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.w.aq a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i32_acquire:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: amoswap.w.aq a0, a1, (a0)
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i32_acquire:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 2
+; RV32I-NEXT: call __atomic_exchange_4
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i32_acquire:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.w.aq a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i32_acquire:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: amoswap.w.aq a0, a1, (a0)
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i32_acquire:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 2
+; RV64I-NEXT: call __atomic_exchange_4
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i32 %val acquire
+ ret i32 %res
+}
+
+define i64 @atomicrmw_xchg_i64_acquire(ptr %ptr, i64 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i64_acquire:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: addi sp, sp, -16
+; RV32IA-ZABHA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IA-ZABHA-NEXT: li a3, 2
+; RV32IA-ZABHA-NEXT: call __atomic_exchange_8
+; RV32IA-ZABHA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IA-ZABHA-NEXT: addi sp, sp, 16
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i64_acquire:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: addi sp, sp, -16
+; RV32IA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IA-NEXT: li a3, 2
+; RV32IA-NEXT: call __atomic_exchange_8
+; RV32IA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IA-NEXT: addi sp, sp, 16
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i64_acquire:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a3, 2
+; RV32I-NEXT: call __atomic_exchange_8
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i64_acquire:
+; RV64IA-ZABHA: # %bb.0:
+; RV64IA-ZABHA-NEXT: amoswap.d.aq a0, a1, (a0)
+; RV64IA-ZABHA-NEXT: ret
+;
+; RV64IA-LABEL: atomicrmw_xchg_i64_acquire:
+; RV64IA: # %bb.0:
+; RV64IA-NEXT: amoswap.d.aq a0, a1, (a0)
+; RV64IA-NEXT: ret
+;
+; RV64I-LABEL: atomicrmw_xchg_i64_acquire:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: li a2, 2
+; RV64I-NEXT: call __atomic_exchange_8
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %res = atomicrmw xchg ptr %ptr, i64 %val acquire
+ ret i64 %res
+}
+
+define i8 @atomicrmw_xchg_i8_release(ptr %ptr, i8 %val) nounwind {
+; RV32IA-ZABHA-LABEL: atomicrmw_xchg_i8_release:
+; RV32IA-ZABHA: # %bb.0:
+; RV32IA-ZABHA-NEXT: amoswap.b.rl a0, a1, (a0)
+; RV32IA-ZABHA-NEXT: ret
+;
+; RV32IA-LABEL: atomicrmw_xchg_i8_release:
+; RV32IA: # %bb.0:
+; RV32IA-NEXT: li a2, 255
+; RV32IA-NEXT: andi a3, a0, -4
+; RV32IA-NEXT: andi a0, a0, 3
+; RV32IA-NEXT: slli a0, a0, 3
+; RV32IA-NEXT: zext.b a1, a1
+; RV32IA-NEXT: sll a2, a2, a0
+; RV32IA-NEXT: sll a1, a1, a0
+; RV32IA-NEXT: .LBB8_1: # =>This Inner Loop Header: Depth=1
+; RV32IA-NEXT: lr.w a4, (a3)
+; RV32IA-NEXT: mv a5, a1
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: and a5, a5, a2
+; RV32IA-NEXT: xor a5, a4, a5
+; RV32IA-NEXT: sc.w.rl a5, a5, (a3)
+; RV32IA-NEXT: bnez a5, .LBB8_1
+; RV32IA-NEXT: # %bb.2:
+; RV32IA-NEXT: srl a0, a4, a0
+; RV32IA-NEXT: ret
+;
+; RV32I-LABEL: atomicrmw_xchg_i8_release:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: li a2, 3
+; RV32I-NEXT: call __atomic_exchange_1
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64IA-ZABHA-LABEL: atomicrmw_xchg_i8_release:
+; RV64IA-ZABHA...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/209983
More information about the llvm-commits
mailing list