gingerBill 2 years ago
parent
commit
233f47cc99
1 changed files with 24 additions and 3 deletions
  1. 24 3
      src/llvm_backend_proc.cpp

+ 24 - 3
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();