[RISCV] Codegen support for atomic operations on RV32I

This patch adds lowering for atomic fences and relies on AtomicExpandPass to
lower atomic loads/stores, atomic rmw, and cmpxchg to __atomic_* libcalls.

test/CodeGen/RISCV/atomic-* are modelled on the exhaustive
test/CodeGen/PPC/atomics-regression.ll, and will prove more useful once RV32A
codegen support is introduced.

Fence mappings are taken from table A.6 in the current draft of version 2.3 of
the RISC-V Instruction Set Manual, which incorporates the memory model changes
and definitions contributed by the RISC-V Memory Consistency Model task group.

Differential Revision: https://reviews.llvm.org/D47587

llvm-svn: 334590
This commit is contained in:
Alex Bradbury 2018-06-13 11:58:46 +00:00
parent 0f8df3e35a
commit dc790dd5d0
7 changed files with 7368 additions and 0 deletions

View File

@ -137,6 +137,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::BlockAddress, XLenVT, Custom);
setOperationAction(ISD::ConstantPool, XLenVT, Custom);
// Atomic operations aren't suported in the base RV32I ISA.
setMaxAtomicSizeInBitsSupported(0);
setBooleanContents(ZeroOrOneBooleanContent);
// Function alignments (log2).

View File

@ -743,6 +743,20 @@ defm : StPat<truncstorei8, SB, GPR>;
defm : StPat<truncstorei16, SH, GPR>;
defm : StPat<store, SW, GPR>;
/// Fences
// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
// Manual: Volume I.
// fence acquire -> fence r, rw
def : Pat<(atomic_fence (i32 4), (imm)), (FENCE 0b10, 0b11)>;
// fence release -> fence rw, w
def : Pat<(atomic_fence (i32 5), (imm)), (FENCE 0b11, 0b1)>;
// fence acq_rel -> fence.tso
def : Pat<(atomic_fence (i32 6), (imm)), (FENCE_TSO)>;
// fence seq_cst -> fence rw, rw
def : Pat<(atomic_fence (i32 7), (imm)), (FENCE 0b11, 0b11)>;
/// Other pseudo-instructions
// Pessimistically assume the stack pointer will be clobbered

View File

@ -75,6 +75,7 @@ public:
return getTM<RISCVTargetMachine>();
}
void addIRPasses() override;
bool addInstSelector() override;
void addPreEmitPass() override;
};
@ -84,6 +85,11 @@ TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) {
return new RISCVPassConfig(*this, PM);
}
void RISCVPassConfig::addIRPasses() {
addPass(createAtomicExpandPass());
TargetPassConfig::addIRPasses();
}
bool RISCVPassConfig::addInstSelector() {
addPass(createRISCVISelDag(getRISCVTargetMachine()));

View File

@ -0,0 +1,720 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I %s
define void @cmpxchg_i8_monotonic_monotonic(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_monotonic_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: mv a3, zero
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val monotonic monotonic
ret void
}
define void @cmpxchg_i8_acquire_monotonic(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_acquire_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 2
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val acquire monotonic
ret void
}
define void @cmpxchg_i8_acquire_acquire(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_acquire_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 2
; RV32I-NEXT: mv a4, a3
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val acquire acquire
ret void
}
define void @cmpxchg_i8_release_monotonic(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_release_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val release monotonic
ret void
}
define void @cmpxchg_i8_release_acquire(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_release_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val release acquire
ret void
}
define void @cmpxchg_i8_acq_rel_monotonic(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_acq_rel_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val acq_rel monotonic
ret void
}
define void @cmpxchg_i8_acq_rel_acquire(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_acq_rel_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val acq_rel acquire
ret void
}
define void @cmpxchg_i8_seq_cst_monotonic(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_seq_cst_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val seq_cst monotonic
ret void
}
define void @cmpxchg_i8_seq_cst_acquire(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_seq_cst_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val seq_cst acquire
ret void
}
define void @cmpxchg_i8_seq_cst_seq_cst(i8* %ptr, i8 %cmp, i8 %val) {
; RV32I-LABEL: cmpxchg_i8_seq_cst_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sb a1, 11(sp)
; RV32I-NEXT: addi a1, sp, 11
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: mv a4, a3
; RV32I-NEXT: call __atomic_compare_exchange_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i8* %ptr, i8 %cmp, i8 %val seq_cst seq_cst
ret void
}
define void @cmpxchg_i16_monotonic_monotonic(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_monotonic_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: mv a3, zero
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val monotonic monotonic
ret void
}
define void @cmpxchg_i16_acquire_monotonic(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_acquire_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 2
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val acquire monotonic
ret void
}
define void @cmpxchg_i16_acquire_acquire(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_acquire_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 2
; RV32I-NEXT: mv a4, a3
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val acquire acquire
ret void
}
define void @cmpxchg_i16_release_monotonic(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_release_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val release monotonic
ret void
}
define void @cmpxchg_i16_release_acquire(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_release_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val release acquire
ret void
}
define void @cmpxchg_i16_acq_rel_monotonic(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_acq_rel_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val acq_rel monotonic
ret void
}
define void @cmpxchg_i16_acq_rel_acquire(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_acq_rel_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val acq_rel acquire
ret void
}
define void @cmpxchg_i16_seq_cst_monotonic(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_seq_cst_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val seq_cst monotonic
ret void
}
define void @cmpxchg_i16_seq_cst_acquire(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_seq_cst_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val seq_cst acquire
ret void
}
define void @cmpxchg_i16_seq_cst_seq_cst(i16* %ptr, i16 %cmp, i16 %val) {
; RV32I-LABEL: cmpxchg_i16_seq_cst_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sh a1, 10(sp)
; RV32I-NEXT: addi a1, sp, 10
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: mv a4, a3
; RV32I-NEXT: call __atomic_compare_exchange_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i16* %ptr, i16 %cmp, i16 %val seq_cst seq_cst
ret void
}
define void @cmpxchg_i32_monotonic_monotonic(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_monotonic_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: mv a3, zero
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val monotonic monotonic
ret void
}
define void @cmpxchg_i32_acquire_monotonic(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_acquire_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 2
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val acquire monotonic
ret void
}
define void @cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_acquire_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 2
; RV32I-NEXT: mv a4, a3
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val acquire acquire
ret void
}
define void @cmpxchg_i32_release_monotonic(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_release_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val release monotonic
ret void
}
define void @cmpxchg_i32_release_acquire(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_release_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val release acquire
ret void
}
define void @cmpxchg_i32_acq_rel_monotonic(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_acq_rel_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val acq_rel monotonic
ret void
}
define void @cmpxchg_i32_acq_rel_acquire(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_acq_rel_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 4
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val acq_rel acquire
ret void
}
define void @cmpxchg_i32_seq_cst_monotonic(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_seq_cst_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val seq_cst monotonic
ret void
}
define void @cmpxchg_i32_seq_cst_acquire(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_seq_cst_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: addi a4, zero, 2
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val seq_cst acquire
ret void
}
define void @cmpxchg_i32_seq_cst_seq_cst(i32* %ptr, i32 %cmp, i32 %val) {
; RV32I-LABEL: cmpxchg_i32_seq_cst_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a1, 8(sp)
; RV32I-NEXT: addi a1, sp, 8
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: mv a4, a3
; RV32I-NEXT: call __atomic_compare_exchange_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i32* %ptr, i32 %cmp, i32 %val seq_cst seq_cst
ret void
}
define void @cmpxchg_i64_monotonic_monotonic(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_monotonic_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, zero
; RV32I-NEXT: mv a5, zero
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val monotonic monotonic
ret void
}
define void @cmpxchg_i64_acquire_monotonic(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_acquire_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a5, zero, 2
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a5
; RV32I-NEXT: mv a5, zero
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val acquire monotonic
ret void
}
define void @cmpxchg_i64_acquire_acquire(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_acquire_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a5, zero, 2
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a5
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val acquire acquire
ret void
}
define void @cmpxchg_i64_release_monotonic(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_release_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a5, zero, 3
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a5
; RV32I-NEXT: mv a5, zero
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val release monotonic
ret void
}
define void @cmpxchg_i64_release_acquire(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_release_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a6, zero, 3
; RV32I-NEXT: addi a5, zero, 2
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a6
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val release acquire
ret void
}
define void @cmpxchg_i64_acq_rel_monotonic(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_acq_rel_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a5, zero, 4
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a5
; RV32I-NEXT: mv a5, zero
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val acq_rel monotonic
ret void
}
define void @cmpxchg_i64_acq_rel_acquire(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_acq_rel_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a6, zero, 4
; RV32I-NEXT: addi a5, zero, 2
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a6
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val acq_rel acquire
ret void
}
define void @cmpxchg_i64_seq_cst_monotonic(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_seq_cst_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a5, zero, 5
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a5
; RV32I-NEXT: mv a5, zero
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val seq_cst monotonic
ret void
}
define void @cmpxchg_i64_seq_cst_acquire(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_seq_cst_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a6, zero, 5
; RV32I-NEXT: addi a5, zero, 2
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a6
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val seq_cst acquire
ret void
}
define void @cmpxchg_i64_seq_cst_seq_cst(i64* %ptr, i64 %cmp, i64 %val) {
; RV32I-LABEL: cmpxchg_i64_seq_cst_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: sw a2, 4(sp)
; RV32I-NEXT: sw a1, 0(sp)
; RV32I-NEXT: mv a1, sp
; RV32I-NEXT: addi a5, zero, 5
; RV32I-NEXT: mv a2, a3
; RV32I-NEXT: mv a3, a4
; RV32I-NEXT: mv a4, a5
; RV32I-NEXT: call __atomic_compare_exchange_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%res = cmpxchg i64* %ptr, i64 %cmp, i64 %val seq_cst seq_cst
ret void
}

View File

@ -0,0 +1,41 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I %s
; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I %s
define void @fence_acquire() nounwind {
; RV32I-LABEL: fence_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: fence r, rw
; RV32I-NEXT: ret
fence acquire
ret void
}
define void @fence_release() nounwind {
; RV32I-LABEL: fence_release:
; RV32I: # %bb.0:
; RV32I-NEXT: fence rw, w
; RV32I-NEXT: ret
fence release
ret void
}
define void @fence_acq_rel() nounwind {
; RV32I-LABEL: fence_acq_rel:
; RV32I: # %bb.0:
; RV32I-NEXT: fence.tso
; RV32I-NEXT: ret
fence acq_rel
ret void
}
define void @fence_seq_cst() nounwind {
; RV32I-LABEL: fence_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: fence rw, rw
; RV32I-NEXT: ret
fence seq_cst
ret void
}

View File

@ -0,0 +1,451 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I %s
define i8 @atomic_load_i8_unordered(i8 *%a) nounwind {
; RV32I-LABEL: atomic_load_i8_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i8, i8* %a unordered, align 1
ret i8 %1
}
define i8 @atomic_load_i8_monotonic(i8 *%a) nounwind {
; RV32I-LABEL: atomic_load_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i8, i8* %a monotonic, align 1
ret i8 %1
}
define i8 @atomic_load_i8_acquire(i8 *%a) nounwind {
; RV32I-LABEL: atomic_load_i8_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 2
; RV32I-NEXT: call __atomic_load_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i8, i8* %a acquire, align 1
ret i8 %1
}
define i8 @atomic_load_i8_seq_cst(i8 *%a) nounwind {
; RV32I-LABEL: atomic_load_i8_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 5
; RV32I-NEXT: call __atomic_load_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i8, i8* %a seq_cst, align 1
ret i8 %1
}
define i16 @atomic_load_i16_unordered(i16 *%a) nounwind {
; RV32I-LABEL: atomic_load_i16_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i16, i16* %a unordered, align 2
ret i16 %1
}
define i16 @atomic_load_i16_monotonic(i16 *%a) nounwind {
; RV32I-LABEL: atomic_load_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i16, i16* %a monotonic, align 2
ret i16 %1
}
define i16 @atomic_load_i16_acquire(i16 *%a) nounwind {
; RV32I-LABEL: atomic_load_i16_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 2
; RV32I-NEXT: call __atomic_load_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i16, i16* %a acquire, align 2
ret i16 %1
}
define i16 @atomic_load_i16_seq_cst(i16 *%a) nounwind {
; RV32I-LABEL: atomic_load_i16_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 5
; RV32I-NEXT: call __atomic_load_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i16, i16* %a seq_cst, align 2
ret i16 %1
}
define i32 @atomic_load_i32_unordered(i32 *%a) nounwind {
; RV32I-LABEL: atomic_load_i32_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i32, i32* %a unordered, align 4
ret i32 %1
}
define i32 @atomic_load_i32_monotonic(i32 *%a) nounwind {
; RV32I-LABEL: atomic_load_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i32, i32* %a monotonic, align 4
ret i32 %1
}
define i32 @atomic_load_i32_acquire(i32 *%a) nounwind {
; RV32I-LABEL: atomic_load_i32_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 2
; RV32I-NEXT: call __atomic_load_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i32, i32* %a acquire, align 4
ret i32 %1
}
define i32 @atomic_load_i32_seq_cst(i32 *%a) nounwind {
; RV32I-LABEL: atomic_load_i32_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 5
; RV32I-NEXT: call __atomic_load_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i32, i32* %a seq_cst, align 4
ret i32 %1
}
define i64 @atomic_load_i64_unordered(i64 *%a) nounwind {
; RV32I-LABEL: atomic_load_i64_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i64, i64* %a unordered, align 8
ret i64 %1
}
define i64 @atomic_load_i64_monotonic(i64 *%a) nounwind {
; RV32I-LABEL: atomic_load_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a1, zero
; RV32I-NEXT: call __atomic_load_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i64, i64* %a monotonic, align 8
ret i64 %1
}
define i64 @atomic_load_i64_acquire(i64 *%a) nounwind {
; RV32I-LABEL: atomic_load_i64_acquire:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 2
; RV32I-NEXT: call __atomic_load_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i64, i64* %a acquire, align 8
ret i64 %1
}
define i64 @atomic_load_i64_seq_cst(i64 *%a) nounwind {
; RV32I-LABEL: atomic_load_i64_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a1, zero, 5
; RV32I-NEXT: call __atomic_load_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
%1 = load atomic i64, i64* %a seq_cst, align 8
ret i64 %1
}
define void @atomic_store_i8_unordered(i8 *%a, i8 %b) nounwind {
; RV32I-LABEL: atomic_store_i8_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a2, zero
; RV32I-NEXT: call __atomic_store_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i8 %b, i8* %a unordered, align 1
ret void
}
define void @atomic_store_i8_monotonic(i8 *%a, i8 %b) nounwind {
; RV32I-LABEL: atomic_store_i8_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a2, zero
; RV32I-NEXT: call __atomic_store_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i8 %b, i8* %a monotonic, align 1
ret void
}
define void @atomic_store_i8_release(i8 *%a, i8 %b) nounwind {
; RV32I-LABEL: atomic_store_i8_release:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a2, zero, 3
; RV32I-NEXT: call __atomic_store_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i8 %b, i8* %a release, align 1
ret void
}
define void @atomic_store_i8_seq_cst(i8 *%a, i8 %b) nounwind {
; RV32I-LABEL: atomic_store_i8_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a2, zero, 5
; RV32I-NEXT: call __atomic_store_1
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i8 %b, i8* %a seq_cst, align 1
ret void
}
define void @atomic_store_i16_unordered(i16 *%a, i16 %b) nounwind {
; RV32I-LABEL: atomic_store_i16_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a2, zero
; RV32I-NEXT: call __atomic_store_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i16 %b, i16* %a unordered, align 2
ret void
}
define void @atomic_store_i16_monotonic(i16 *%a, i16 %b) nounwind {
; RV32I-LABEL: atomic_store_i16_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a2, zero
; RV32I-NEXT: call __atomic_store_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i16 %b, i16* %a monotonic, align 2
ret void
}
define void @atomic_store_i16_release(i16 *%a, i16 %b) nounwind {
; RV32I-LABEL: atomic_store_i16_release:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a2, zero, 3
; RV32I-NEXT: call __atomic_store_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i16 %b, i16* %a release, align 2
ret void
}
define void @atomic_store_i16_seq_cst(i16 *%a, i16 %b) nounwind {
; RV32I-LABEL: atomic_store_i16_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a2, zero, 5
; RV32I-NEXT: call __atomic_store_2
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i16 %b, i16* %a seq_cst, align 2
ret void
}
define void @atomic_store_i32_unordered(i32 *%a, i32 %b) nounwind {
; RV32I-LABEL: atomic_store_i32_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a2, zero
; RV32I-NEXT: call __atomic_store_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i32 %b, i32* %a unordered, align 4
ret void
}
define void @atomic_store_i32_monotonic(i32 *%a, i32 %b) nounwind {
; RV32I-LABEL: atomic_store_i32_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a2, zero
; RV32I-NEXT: call __atomic_store_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i32 %b, i32* %a monotonic, align 4
ret void
}
define void @atomic_store_i32_release(i32 *%a, i32 %b) nounwind {
; RV32I-LABEL: atomic_store_i32_release:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a2, zero, 3
; RV32I-NEXT: call __atomic_store_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i32 %b, i32* %a release, align 4
ret void
}
define void @atomic_store_i32_seq_cst(i32 *%a, i32 %b) nounwind {
; RV32I-LABEL: atomic_store_i32_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a2, zero, 5
; RV32I-NEXT: call __atomic_store_4
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i32 %b, i32* %a seq_cst, align 4
ret void
}
define void @atomic_store_i64_unordered(i64 *%a, i64 %b) nounwind {
; RV32I-LABEL: atomic_store_i64_unordered:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a3, zero
; RV32I-NEXT: call __atomic_store_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i64 %b, i64* %a unordered, align 8
ret void
}
define void @atomic_store_i64_monotonic(i64 *%a, i64 %b) nounwind {
; RV32I-LABEL: atomic_store_i64_monotonic:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: mv a3, zero
; RV32I-NEXT: call __atomic_store_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i64 %b, i64* %a monotonic, align 8
ret void
}
define void @atomic_store_i64_release(i64 *%a, i64 %b) nounwind {
; RV32I-LABEL: atomic_store_i64_release:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a3, zero, 3
; RV32I-NEXT: call __atomic_store_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i64 %b, i64* %a release, align 8
ret void
}
define void @atomic_store_i64_seq_cst(i64 *%a, i64 %b) nounwind {
; RV32I-LABEL: atomic_store_i64_seq_cst:
; RV32I: # %bb.0:
; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: sw ra, 12(sp)
; RV32I-NEXT: addi a3, zero, 5
; RV32I-NEXT: call __atomic_store_8
; RV32I-NEXT: lw ra, 12(sp)
; RV32I-NEXT: addi sp, sp, 16
; RV32I-NEXT: ret
store atomic i64 %b, i64* %a seq_cst, align 8
ret void
}

File diff suppressed because it is too large Load Diff