forked from OSchip/llvm-project
[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:
parent
0f8df3e35a
commit
dc790dd5d0
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue