diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index b9ee0eeb5..b9f2c2db2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2304,7 +2304,15 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu break; case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break; case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; - case BuiltinProc_atomic_store_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[2])); break; + case BuiltinProc_atomic_store_explicit: + { + auto ordering = llvm_atomic_ordering_from_odin(ce->args[2]); + LLVMSetOrdering(instr, ordering); + if (ordering == LLVMAtomicOrderingUnordered) { + LLVMSetVolatile(instr, true); + } + } + break; } LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type))); @@ -2330,7 +2338,15 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu break; case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break; case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; - case BuiltinProc_atomic_load_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[1])); break; + case BuiltinProc_atomic_load_explicit: + { + auto ordering = llvm_atomic_ordering_from_odin(ce->args[1]); + LLVMSetOrdering(instr, ordering); + if (ordering == LLVMAtomicOrderingUnordered) { + LLVMSetVolatile(instr, true); + } + } + break; } LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type))); @@ -2400,6 +2416,9 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu lbValue res = {}; res.value = LLVMBuildAtomicRMW(p->builder, op, dst.value, val.value, ordering, false); res.type = tv.type; + if (ordering == LLVMAtomicOrderingUnordered) { + LLVMSetVolatile(res.value, true); + } return res; } @@ -2425,7 +2444,6 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_atomic_compare_exchange_weak_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = true; break; } - // TODO(bill): Figure out how to make it weak LLVMBool single_threaded = false; LLVMValueRef value = LLVMBuildAtomicCmpXchg( @@ -2436,6 +2454,9 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu single_threaded ); LLVMSetWeak(value, weak); + if (success_ordering == LLVMAtomicOrderingUnordered || failure_ordering == LLVMAtomicOrderingUnordered) { + LLVMSetVolatile(value, true); + } if (is_type_tuple(tv.type)) { Type *fix_typed = alloc_type_tuple();