$ ./bin/crystal --version
Using compiled compiler at .build/crystal
Crystal 1.8.0-dev [58fb584cb87] (2023-01-21)
LLVM: 14.0.1
Default target: aarch64-apple-darwin21.6.0
$ ./bin/crystal build --emit=llvm-ir -Dpreview_mt bug.ign.cr
$ llvm-as ./bug.ign.ll -o ./bug.ign.bc
$ llc ./bug.ign.bc -o ./bug.ign.s
def swap(value : T)
Ops.atomicrmw(:xchg, pointerof(@value), value, :sequentially_consistent, false)
end
def codegen_primitive_atomicrmw(call, node, target_def, call_args)
call = check_atomic_call(call, target_def)
op, ptr, val, ordering, _ = call_args
op = atomicrwm_bin_op_get_const(call.args[0], op)
ordering = atomic_ordering_get_const(call.args[-2], ordering)
singlethread = bool_from_bool_literal(call.args[-1])
builder.atomicrmw(op, ptr, val, ordering, singlethread)
end
; Function Attrs: uwtable
define internal i32 @"*Atomic(Int32)@Atomic(T)#swap<Int32>:Int32"(%"Atomic(Int32)"* %self, i32 %value) #0 !dbg !2689 {
entry:
%0 = getelementptr inbounds %"Atomic(Int32)", %"Atomic(Int32)"* %self, i32 0, i32 0, !dbg !2690
%1 = load i32, i32* %0, align 4, !dbg !2690
br label %atomicrmw.start, !dbg !2690
atomicrmw.start: ; preds = %atomicrmw.start, %entry
%loaded = phi i32 [ %1, %entry ], [ %newloaded, %atomicrmw.start ], !dbg !2690
%2 = cmpxchg i32* %0, i32 %loaded, i32 %value seq_cst seq_cst, align 4, !dbg !2690
%success = extractvalue { i32, i1 } %2, 1, !dbg !2690
%newloaded = extractvalue { i32, i1 } %2, 0, !dbg !2690
br i1 %success, label %atomicrmw.end, label %atomicrmw.start, !dbg !2690
atomicrmw.end: ; preds = %atomicrmw.start
ret i32 %newloaded, !dbg !2690
}
.p2align 2 ; -- Begin function *Atomic(Int32)@Atomic(T)#swap<Int32>:Int32
"_*Atomic(Int32)@Atomic(T)#swap<Int32>:Int32": ; @"*Atomic(Int32)@Atomic(T)#swap<Int32>:Int32"
Lfunc_begin491:
.loc 68 161 0 ; atomic.cr:161:0
.cfi_startproc
; %bb.0: ; %entry
stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
mov x29, sp
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
Ltmp1981:
.loc 68 161 3 prologue_end ; atomic.cr:161:3
ldr w8, [x0]
b LBB491_2
LBB491_1: ; %cmpxchg.nostore
; in Loop: Header=BB491_2 Depth=1
.loc 68 0 3 is_stmt 0 ; atomic.cr:0:3
mov w9, wzr
.loc 68 161 3 ; atomic.cr:161:3
clrex
cbnz w9, LBB491_6
LBB491_2: ; %atomicrmw.start
; =>This Loop Header: Depth=1
; Child Loop BB491_3 Depth 2
mov w9, w8
LBB491_3: ; %cmpxchg.start
; Parent Loop BB491_2 Depth=1
; => This Inner Loop Header: Depth=2
ldaxr w8, [x0]
cmp w8, w9
b.ne LBB491_1
; %bb.4: ; %cmpxchg.trystore
; in Loop: Header=BB491_3 Depth=2
stlxr w10, w1, [x0]
cbnz w10, LBB491_3
; %bb.5: ; in Loop: Header=BB491_2 Depth=1
.loc 68 0 3 ; atomic.cr:0:3
mov w9, #1
.loc 68 161 3 ; atomic.cr:161:3
cbz w9, LBB491_2
LBB491_6: ; %atomicrmw.end
mov w0, w8
ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
ret
Ltmp1982:
Lfunc_end491:
.cfi_endproc
; -- End function