authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 14:47:26-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 14:47:26-04:00
log90e64bc620edc3f3c3a2c16d01b7ca2eefc02429
tree42280ec202a86a5fab37ed5b6e38f38792ab8042
parenta5cb0f77d11bdcc504fe3e6afa928c88de821518
signature Commit is signed but in an unrecognized format.

fix cmpxchg with discarded result


2 files changed, 17 insertions(+), 1 deletions(-)

src/codegen.cpp+7-1
...@@ -4458,8 +4458,14 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn...@@ -4458,8 +4458,14 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
4458 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");4458 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
4459 }4459 }
44604460
4461 // When the cmpxchg is discarded, the result location will have no bits.
4462 if (!type_has_bits(instruction->result_loc->value.type)) {
4463 return nullptr;
4464 }
4465
4461 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);4466 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
4462 assert(type_has_bits(child_type));4467 src_assert(result_loc != nullptr, instruction->base.source_node);
4468 src_assert(type_has_bits(child_type), instruction->base.source_node);
44634469
4464 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");4470 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4465 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");4471 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
test/stage1/behavior/atomics.zig+10
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
3const builtin = @import("builtin");4const builtin = @import("builtin");
4const AtomicRmwOp = builtin.AtomicRmwOp;5const AtomicRmwOp = builtin.AtomicRmwOp;
5const AtomicOrder = builtin.AtomicOrder;6const AtomicOrder = builtin.AtomicOrder;
...@@ -90,3 +91,12 @@ test "cmpxchg with ptr" {...@@ -90,3 +91,12 @@ test "cmpxchg with ptr" {
90// expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);91// expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
91// expect(x == 42);92// expect(x == 42);
92//}93//}
94
95test "cmpxchg with ignored result" {
96 var x: i32 = 1234;
97 var ptr = &x;
98
99 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
100
101 expectEqual(i32(5678), x);
102}