@@ -248,14 +248,15 @@ const binoptable = [
248
248
(:umin , min, LLVM. API. LLVMAtomicRMWBinOpUMin),
249
249
(:fadd , + , LLVM. API. LLVMAtomicRMWBinOpFAdd),
250
250
(:fsub , - , LLVM. API. LLVMAtomicRMWBinOpFSub),
251
+ (:fmax , max, LLVM. API. LLVMAtomicRMWBinOpFMax),
252
+ (:fmin , min, LLVM. API. LLVMAtomicRMWBinOpFMin),
251
253
]
252
- if VERSION ≥ v " 1.10-"
253
- push! (binoptable, (:fmax , max, LLVM. API. LLVMAtomicRMWBinOpFMax))
254
- push! (binoptable, (:fmin , min, LLVM. API. LLVMAtomicRMWBinOpFMin))
255
- end
256
254
257
255
const AtomicRMWBinOpVal = Union{(Val{binop} for (_, _, binop) in binoptable). .. }
258
256
257
+ # LLVM API accepts string literal as a syncscope argument.
258
+ @inline syncscope_to_string (:: Type{Val{S}} ) where {S} = string (S)
259
+
259
260
@generated function llvm_atomic_op (
260
261
binop:: AtomicRMWBinOpVal ,
261
262
ptr:: LLVMPtr{T,A} ,
@@ -293,6 +294,40 @@ const AtomicRMWBinOpVal = Union{(Val{binop} for (_, _, binop) in binoptable)...}
293
294
end
294
295
end
295
296
297
+ @generated function llvm_atomic_op (
298
+ binop:: AtomicRMWBinOpVal ,
299
+ ptr:: LLVMPtr{T,A} ,
300
+ val:: T ,
301
+ order:: LLVMOrderingVal ,
302
+ syncscope:: Val{S} ,
303
+ ) where {T,A,S}
304
+ @dispose ctx = Context () begin
305
+ T_val = convert (LLVMType, T)
306
+ T_ptr = convert (LLVMType, ptr)
307
+
308
+ T_typed_ptr = LLVM. PointerType (T_val, A)
309
+ llvm_f, _ = create_function (T_val, [T_ptr, T_val])
310
+
311
+ @dispose builder = IRBuilder () begin
312
+ entry = BasicBlock (llvm_f, " entry" )
313
+ position! (builder, entry)
314
+
315
+ typed_ptr = bitcast! (builder, parameters (llvm_f)[1 ], T_typed_ptr)
316
+ rv = atomic_rmw! (
317
+ builder,
318
+ _valueof (binop ()),
319
+ typed_ptr,
320
+ parameters (llvm_f)[2 ],
321
+ _valueof (order ()),
322
+ syncscope_to_string (syncscope),
323
+ )
324
+
325
+ ret! (builder, rv)
326
+ end
327
+ call_function (llvm_f, T, Tuple{LLVMPtr{T,A},T}, :ptr , :val )
328
+ end
329
+ end
330
+
296
331
@inline function atomic_pointermodify (pointer, op:: OP , x, order:: Symbol ) where {OP}
297
332
@dynamic_order (order) do order
298
333
atomic_pointermodify (pointer, op, x, order)
@@ -359,8 +394,18 @@ for (opname, op, llvmop) in binoptable
359
394
:: $ (typeof (op)),
360
395
x:: $T ,
361
396
order:: AtomicOrdering ,
362
- )
363
- old = llvm_atomic_op ($ (Val (llvmop)), ptr, x, llvm_from_julia_ordering (order))
397
+ syncscope:: Val{S} = Val {:system} (),
398
+ ) where {S}
399
+ old =
400
+ syncscope isa Val{:system } ?
401
+ llvm_atomic_op ($ (Val (llvmop)), ptr, x, llvm_from_julia_ordering (order)) :
402
+ llvm_atomic_op (
403
+ $ (Val (llvmop)),
404
+ ptr,
405
+ x,
406
+ llvm_from_julia_ordering (order),
407
+ syncscope,
408
+ )
364
409
return old => $ op (old, x)
365
410
end
366
411
end
0 commit comments