Skip to content

Commit

Permalink
[CHERI-RISC-V] Expand capability AtomicRMW XCHG in hybrid mode
Browse files Browse the repository at this point in the history
This allows expanding e.g. `atomicrmw xchg i32 addrspace(200)*` without a
library call. Code generation could be improved by adding an explicit
pseudo but that can be done as a follow-up change
  • Loading branch information
arichardson committed Aug 15, 2022
1 parent 4c2ad4a commit 9aa0d2f
Show file tree
Hide file tree
Showing 3 changed files with 433 additions and 111 deletions.
12 changes: 9 additions & 3 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9296,8 +9296,13 @@ RISCVTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
// For capability pointers we must always use the smallest possible type
// instead of promoting to i32/i64 to ensure we don't trigger bounds errors.
const DataLayout &DL = AI->getModule()->getDataLayout();
if (DL.isFatPointer(AI->getPointerOperand()->getType()))
if (DL.isFatPointer(AI->getPointerOperand()->getType())) {
if (!RISCVABI::isCheriPureCapABI(Subtarget.getTargetABI()) &&
AI->getOperation() == AtomicRMWInst::Xchg &&
DL.isFatPointer(AI->getPointerOperand()->getType()))
return AtomicExpansionKind::CmpXChg;
return AtomicExpansionKind::None;
}

uint64_t Size = DL.getTypeSizeInBits(AI->getType()).getFixedSize();
if (Size == 8 || Size == 16)
Expand Down Expand Up @@ -9450,8 +9455,9 @@ bool RISCVTargetLowering::supportsAtomicOperation(const DataLayout &DL,
return false;
} else {
// In the hybrid ABI with explicit capability addressing, we support all
// integer operations, but do not handle capability arguments.
if (DL.isFatPointer(PointerTy) && DL.isFatPointer(ValueTy))
// integer operations, but only handle XCHG for capability arguments.
if (DL.isFatPointer(PointerTy) && DL.isFatPointer(ValueTy) &&
RMWI->getOperation() != AtomicRMWInst::Xchg)
return false;
}
}
Expand Down
266 changes: 212 additions & 54 deletions llvm/test/CodeGen/CHERI-Generic/RISCV32/atomic-rmw-cap-ptr-arg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,42 @@ define i32 addrspace(200)* @atomic_cap_ptr_xchg_sc(i32 addrspace(200)* addrspace
; PURECAP-LIBCALLS-NEXT: cincoffset csp, csp, 16
; PURECAP-LIBCALLS-NEXT: cret
;
; HYBRID-LABEL: atomic_cap_ptr_xchg_sc:
; HYBRID: # %bb.0:
; HYBRID-NEXT: addi sp, sp, -16
; HYBRID-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-NEXT: addi a2, zero, 5
; HYBRID-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-NEXT: addi sp, sp, 16
; HYBRID-NEXT: ret
; HYBRID-ATOMICS-LABEL: atomic_cap_ptr_xchg_sc:
; HYBRID-ATOMICS: # %bb.0:
; HYBRID-ATOMICS-NEXT: fence rw, rw
; HYBRID-ATOMICS-NEXT: lc.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: .LBB0_1: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # =>This Loop Header: Depth=1
; HYBRID-ATOMICS-NEXT: # Child Loop BB0_3 Depth 2
; HYBRID-ATOMICS-NEXT: cmove ca3, ca2
; HYBRID-ATOMICS-NEXT: cmove ca2, ca1
; HYBRID-ATOMICS-NEXT: .LBB0_3: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # Parent Loop BB0_1 Depth=1
; HYBRID-ATOMICS-NEXT: # => This Inner Loop Header: Depth=2
; HYBRID-ATOMICS-NEXT: lr.c.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB0_5
; HYBRID-ATOMICS-NEXT: # %bb.4: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB0_3 Depth=2
; HYBRID-ATOMICS-NEXT: cmove ca4, ca2
; HYBRID-ATOMICS-NEXT: sc.c.cap ca4, (ca0)
; HYBRID-ATOMICS-NEXT: bnez a4, .LBB0_3
; HYBRID-ATOMICS-NEXT: .LBB0_5: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB0_1 Depth=1
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB0_1
; HYBRID-ATOMICS-NEXT: # %bb.2: # %atomicrmw.end
; HYBRID-ATOMICS-NEXT: fence r, rw
; HYBRID-ATOMICS-NEXT: cmove ca0, ca2
; HYBRID-ATOMICS-NEXT: ret
;
; HYBRID-LIBCALLS-LABEL: atomic_cap_ptr_xchg_sc:
; HYBRID-LIBCALLS: # %bb.0:
; HYBRID-LIBCALLS-NEXT: addi sp, sp, -16
; HYBRID-LIBCALLS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-LIBCALLS-NEXT: addi a2, zero, 5
; HYBRID-LIBCALLS-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-LIBCALLS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-LIBCALLS-NEXT: addi sp, sp, 16
; HYBRID-LIBCALLS-NEXT: ret
%tmp = atomicrmw xchg i32 addrspace(200)* addrspace(200)* %ptr, i32 addrspace(200)* %val seq_cst
ret i32 addrspace(200)* %tmp
}
Expand All @@ -52,15 +79,40 @@ define i32 addrspace(200)* @atomic_cap_ptr_xchg_relaxed(i32 addrspace(200)* addr
; PURECAP-LIBCALLS-NEXT: cincoffset csp, csp, 16
; PURECAP-LIBCALLS-NEXT: cret
;
; HYBRID-LABEL: atomic_cap_ptr_xchg_relaxed:
; HYBRID: # %bb.0:
; HYBRID-NEXT: addi sp, sp, -16
; HYBRID-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-NEXT: mv a2, zero
; HYBRID-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-NEXT: addi sp, sp, 16
; HYBRID-NEXT: ret
; HYBRID-ATOMICS-LABEL: atomic_cap_ptr_xchg_relaxed:
; HYBRID-ATOMICS: # %bb.0:
; HYBRID-ATOMICS-NEXT: lc.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: .LBB1_1: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # =>This Loop Header: Depth=1
; HYBRID-ATOMICS-NEXT: # Child Loop BB1_3 Depth 2
; HYBRID-ATOMICS-NEXT: cmove ca3, ca2
; HYBRID-ATOMICS-NEXT: cmove ca2, ca1
; HYBRID-ATOMICS-NEXT: .LBB1_3: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # Parent Loop BB1_1 Depth=1
; HYBRID-ATOMICS-NEXT: # => This Inner Loop Header: Depth=2
; HYBRID-ATOMICS-NEXT: lr.c.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB1_5
; HYBRID-ATOMICS-NEXT: # %bb.4: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB1_3 Depth=2
; HYBRID-ATOMICS-NEXT: cmove ca4, ca2
; HYBRID-ATOMICS-NEXT: sc.c.cap ca4, (ca0)
; HYBRID-ATOMICS-NEXT: bnez a4, .LBB1_3
; HYBRID-ATOMICS-NEXT: .LBB1_5: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB1_1 Depth=1
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB1_1
; HYBRID-ATOMICS-NEXT: # %bb.2: # %atomicrmw.end
; HYBRID-ATOMICS-NEXT: cmove ca0, ca2
; HYBRID-ATOMICS-NEXT: ret
;
; HYBRID-LIBCALLS-LABEL: atomic_cap_ptr_xchg_relaxed:
; HYBRID-LIBCALLS: # %bb.0:
; HYBRID-LIBCALLS-NEXT: addi sp, sp, -16
; HYBRID-LIBCALLS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-LIBCALLS-NEXT: mv a2, zero
; HYBRID-LIBCALLS-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-LIBCALLS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-LIBCALLS-NEXT: addi sp, sp, 16
; HYBRID-LIBCALLS-NEXT: ret
%tmp = atomicrmw xchg i32 addrspace(200)* addrspace(200)* %ptr, i32 addrspace(200)* %val monotonic
ret i32 addrspace(200)* %tmp
}
Expand All @@ -81,15 +133,41 @@ define i32 addrspace(200)* @atomic_cap_ptr_xchg_acquire(i32 addrspace(200)* addr
; PURECAP-LIBCALLS-NEXT: cincoffset csp, csp, 16
; PURECAP-LIBCALLS-NEXT: cret
;
; HYBRID-LABEL: atomic_cap_ptr_xchg_acquire:
; HYBRID: # %bb.0:
; HYBRID-NEXT: addi sp, sp, -16
; HYBRID-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-NEXT: addi a2, zero, 2
; HYBRID-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-NEXT: addi sp, sp, 16
; HYBRID-NEXT: ret
; HYBRID-ATOMICS-LABEL: atomic_cap_ptr_xchg_acquire:
; HYBRID-ATOMICS: # %bb.0:
; HYBRID-ATOMICS-NEXT: cmove ca2, ca0
; HYBRID-ATOMICS-NEXT: lc.cap ca0, (ca0)
; HYBRID-ATOMICS-NEXT: .LBB2_1: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # =>This Loop Header: Depth=1
; HYBRID-ATOMICS-NEXT: # Child Loop BB2_3 Depth 2
; HYBRID-ATOMICS-NEXT: cmove ca3, ca0
; HYBRID-ATOMICS-NEXT: cmove ca0, ca1
; HYBRID-ATOMICS-NEXT: .LBB2_3: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # Parent Loop BB2_1 Depth=1
; HYBRID-ATOMICS-NEXT: # => This Inner Loop Header: Depth=2
; HYBRID-ATOMICS-NEXT: lr.c.cap ca0, (ca2)
; HYBRID-ATOMICS-NEXT: bne a0, a3, .LBB2_5
; HYBRID-ATOMICS-NEXT: # %bb.4: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB2_3 Depth=2
; HYBRID-ATOMICS-NEXT: cmove ca4, ca0
; HYBRID-ATOMICS-NEXT: sc.c.cap ca4, (ca2)
; HYBRID-ATOMICS-NEXT: bnez a4, .LBB2_3
; HYBRID-ATOMICS-NEXT: .LBB2_5: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB2_1 Depth=1
; HYBRID-ATOMICS-NEXT: bne a0, a3, .LBB2_1
; HYBRID-ATOMICS-NEXT: # %bb.2: # %atomicrmw.end
; HYBRID-ATOMICS-NEXT: fence r, rw
; HYBRID-ATOMICS-NEXT: ret
;
; HYBRID-LIBCALLS-LABEL: atomic_cap_ptr_xchg_acquire:
; HYBRID-LIBCALLS: # %bb.0:
; HYBRID-LIBCALLS-NEXT: addi sp, sp, -16
; HYBRID-LIBCALLS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-LIBCALLS-NEXT: addi a2, zero, 2
; HYBRID-LIBCALLS-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-LIBCALLS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-LIBCALLS-NEXT: addi sp, sp, 16
; HYBRID-LIBCALLS-NEXT: ret
%tmp = atomicrmw xchg i32 addrspace(200)* addrspace(200)* %ptr, i32 addrspace(200)* %val acquire
ret i32 addrspace(200)* %tmp
}
Expand All @@ -110,15 +188,41 @@ define i32 addrspace(200)* @atomic_cap_ptr_xchg_rel(i32 addrspace(200)* addrspac
; PURECAP-LIBCALLS-NEXT: cincoffset csp, csp, 16
; PURECAP-LIBCALLS-NEXT: cret
;
; HYBRID-LABEL: atomic_cap_ptr_xchg_rel:
; HYBRID: # %bb.0:
; HYBRID-NEXT: addi sp, sp, -16
; HYBRID-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-NEXT: addi a2, zero, 3
; HYBRID-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-NEXT: addi sp, sp, 16
; HYBRID-NEXT: ret
; HYBRID-ATOMICS-LABEL: atomic_cap_ptr_xchg_rel:
; HYBRID-ATOMICS: # %bb.0:
; HYBRID-ATOMICS-NEXT: fence rw, w
; HYBRID-ATOMICS-NEXT: lc.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: .LBB3_1: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # =>This Loop Header: Depth=1
; HYBRID-ATOMICS-NEXT: # Child Loop BB3_3 Depth 2
; HYBRID-ATOMICS-NEXT: cmove ca3, ca2
; HYBRID-ATOMICS-NEXT: cmove ca2, ca1
; HYBRID-ATOMICS-NEXT: .LBB3_3: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # Parent Loop BB3_1 Depth=1
; HYBRID-ATOMICS-NEXT: # => This Inner Loop Header: Depth=2
; HYBRID-ATOMICS-NEXT: lr.c.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB3_5
; HYBRID-ATOMICS-NEXT: # %bb.4: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB3_3 Depth=2
; HYBRID-ATOMICS-NEXT: cmove ca4, ca2
; HYBRID-ATOMICS-NEXT: sc.c.cap ca4, (ca0)
; HYBRID-ATOMICS-NEXT: bnez a4, .LBB3_3
; HYBRID-ATOMICS-NEXT: .LBB3_5: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB3_1 Depth=1
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB3_1
; HYBRID-ATOMICS-NEXT: # %bb.2: # %atomicrmw.end
; HYBRID-ATOMICS-NEXT: cmove ca0, ca2
; HYBRID-ATOMICS-NEXT: ret
;
; HYBRID-LIBCALLS-LABEL: atomic_cap_ptr_xchg_rel:
; HYBRID-LIBCALLS: # %bb.0:
; HYBRID-LIBCALLS-NEXT: addi sp, sp, -16
; HYBRID-LIBCALLS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-LIBCALLS-NEXT: addi a2, zero, 3
; HYBRID-LIBCALLS-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-LIBCALLS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-LIBCALLS-NEXT: addi sp, sp, 16
; HYBRID-LIBCALLS-NEXT: ret
%tmp = atomicrmw xchg i32 addrspace(200)* addrspace(200)* %ptr, i32 addrspace(200)* %val release
ret i32 addrspace(200)* %tmp
}
Expand All @@ -139,15 +243,42 @@ define i32 addrspace(200)* @atomic_cap_ptr_xchg_acq_rel(i32 addrspace(200)* addr
; PURECAP-LIBCALLS-NEXT: cincoffset csp, csp, 16
; PURECAP-LIBCALLS-NEXT: cret
;
; HYBRID-LABEL: atomic_cap_ptr_xchg_acq_rel:
; HYBRID: # %bb.0:
; HYBRID-NEXT: addi sp, sp, -16
; HYBRID-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-NEXT: addi a2, zero, 4
; HYBRID-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-NEXT: addi sp, sp, 16
; HYBRID-NEXT: ret
; HYBRID-ATOMICS-LABEL: atomic_cap_ptr_xchg_acq_rel:
; HYBRID-ATOMICS: # %bb.0:
; HYBRID-ATOMICS-NEXT: fence rw, w
; HYBRID-ATOMICS-NEXT: lc.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: .LBB4_1: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # =>This Loop Header: Depth=1
; HYBRID-ATOMICS-NEXT: # Child Loop BB4_3 Depth 2
; HYBRID-ATOMICS-NEXT: cmove ca3, ca2
; HYBRID-ATOMICS-NEXT: cmove ca2, ca1
; HYBRID-ATOMICS-NEXT: .LBB4_3: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # Parent Loop BB4_1 Depth=1
; HYBRID-ATOMICS-NEXT: # => This Inner Loop Header: Depth=2
; HYBRID-ATOMICS-NEXT: lr.c.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB4_5
; HYBRID-ATOMICS-NEXT: # %bb.4: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB4_3 Depth=2
; HYBRID-ATOMICS-NEXT: cmove ca4, ca2
; HYBRID-ATOMICS-NEXT: sc.c.cap ca4, (ca0)
; HYBRID-ATOMICS-NEXT: bnez a4, .LBB4_3
; HYBRID-ATOMICS-NEXT: .LBB4_5: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB4_1 Depth=1
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB4_1
; HYBRID-ATOMICS-NEXT: # %bb.2: # %atomicrmw.end
; HYBRID-ATOMICS-NEXT: fence r, rw
; HYBRID-ATOMICS-NEXT: cmove ca0, ca2
; HYBRID-ATOMICS-NEXT: ret
;
; HYBRID-LIBCALLS-LABEL: atomic_cap_ptr_xchg_acq_rel:
; HYBRID-LIBCALLS: # %bb.0:
; HYBRID-LIBCALLS-NEXT: addi sp, sp, -16
; HYBRID-LIBCALLS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-LIBCALLS-NEXT: addi a2, zero, 4
; HYBRID-LIBCALLS-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-LIBCALLS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-LIBCALLS-NEXT: addi sp, sp, 16
; HYBRID-LIBCALLS-NEXT: ret
%tmp = atomicrmw xchg i32 addrspace(200)* addrspace(200)* %ptr, i32 addrspace(200)* %val acq_rel
ret i32 addrspace(200)* %tmp
}
Expand All @@ -169,15 +300,42 @@ define i32 addrspace(200)* @atomic_cap_ptr_xchg_i32ptr(i32 addrspace(200)* addrs
; PURECAP-LIBCALLS-NEXT: cincoffset csp, csp, 16
; PURECAP-LIBCALLS-NEXT: cret
;
; HYBRID-LABEL: atomic_cap_ptr_xchg_i32ptr:
; HYBRID: # %bb.0:
; HYBRID-NEXT: addi sp, sp, -16
; HYBRID-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-NEXT: addi a2, zero, 4
; HYBRID-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-NEXT: addi sp, sp, 16
; HYBRID-NEXT: ret
; HYBRID-ATOMICS-LABEL: atomic_cap_ptr_xchg_i32ptr:
; HYBRID-ATOMICS: # %bb.0:
; HYBRID-ATOMICS-NEXT: fence rw, w
; HYBRID-ATOMICS-NEXT: lc.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: .LBB5_1: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # =>This Loop Header: Depth=1
; HYBRID-ATOMICS-NEXT: # Child Loop BB5_3 Depth 2
; HYBRID-ATOMICS-NEXT: cmove ca3, ca2
; HYBRID-ATOMICS-NEXT: cmove ca2, ca1
; HYBRID-ATOMICS-NEXT: .LBB5_3: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # Parent Loop BB5_1 Depth=1
; HYBRID-ATOMICS-NEXT: # => This Inner Loop Header: Depth=2
; HYBRID-ATOMICS-NEXT: lr.c.cap ca2, (ca0)
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB5_5
; HYBRID-ATOMICS-NEXT: # %bb.4: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB5_3 Depth=2
; HYBRID-ATOMICS-NEXT: cmove ca4, ca2
; HYBRID-ATOMICS-NEXT: sc.c.cap ca4, (ca0)
; HYBRID-ATOMICS-NEXT: bnez a4, .LBB5_3
; HYBRID-ATOMICS-NEXT: .LBB5_5: # %atomicrmw.start
; HYBRID-ATOMICS-NEXT: # in Loop: Header=BB5_1 Depth=1
; HYBRID-ATOMICS-NEXT: bne a2, a3, .LBB5_1
; HYBRID-ATOMICS-NEXT: # %bb.2: # %atomicrmw.end
; HYBRID-ATOMICS-NEXT: fence r, rw
; HYBRID-ATOMICS-NEXT: cmove ca0, ca2
; HYBRID-ATOMICS-NEXT: ret
;
; HYBRID-LIBCALLS-LABEL: atomic_cap_ptr_xchg_i32ptr:
; HYBRID-LIBCALLS: # %bb.0:
; HYBRID-LIBCALLS-NEXT: addi sp, sp, -16
; HYBRID-LIBCALLS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; HYBRID-LIBCALLS-NEXT: addi a2, zero, 4
; HYBRID-LIBCALLS-NEXT: call __atomic_exchange_cap_c@plt
; HYBRID-LIBCALLS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; HYBRID-LIBCALLS-NEXT: addi sp, sp, 16
; HYBRID-LIBCALLS-NEXT: ret
%tmp = atomicrmw xchg i32 addrspace(200)* addrspace(200)* %ptr, i32 addrspace(200)* %val acq_rel
ret i32 addrspace(200)* %tmp
}
Expand Down
Loading

0 comments on commit 9aa0d2f

Please sign in to comment.