Commit 90e64bc620

Andrew Kelley <andrew@ziglang.org>
2019-08-02 20:47:26
fix cmpxchg with discarded result
1 parent a5cb0f7
Changed files (2)
src
test
stage1
behavior
src/codegen.cpp
@@ -4458,8 +4458,14 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
         return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
     }
 
+    // When the cmpxchg is discarded, the result location will have no bits.
+    if (!type_has_bits(instruction->result_loc->value.type)) {
+        return nullptr;
+    }
+
     LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
-    assert(type_has_bits(child_type));
+    src_assert(result_loc != nullptr, instruction->base.source_node);
+    src_assert(type_has_bits(child_type), instruction->base.source_node);
 
     LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
     LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
test/stage1/behavior/atomics.zig
@@ -1,5 +1,6 @@
 const std = @import("std");
 const expect = std.testing.expect;
+const expectEqual = std.testing.expectEqual;
 const builtin = @import("builtin");
 const AtomicRmwOp = builtin.AtomicRmwOp;
 const AtomicOrder = builtin.AtomicOrder;
@@ -90,3 +91,12 @@ test "cmpxchg with ptr" {
 //    expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
 //    expect(x == 42);
 //}
+
+test "cmpxchg with ignored result" {
+    var x: i32 = 1234;
+    var ptr = &x;
+
+    _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
+
+    expectEqual(i32(5678), x);
+}