diff --git a/doc/langref.html.in b/doc/langref.html.in index 447d545975..0dedb48b1c 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -6728,17 +6728,8 @@ async fn func(y: *i32) void { This builtin function atomically dereferences a pointer and returns the value.
- {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, a float, - an integer whose bit count meets these requirements: -
-- TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe - we can remove this restriction + {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, + an integer or an enum.
{#header_close#} {#header_open|@atomicRmw#} @@ -6747,17 +6738,8 @@ async fn func(y: *i32) void { This builtin function atomically modifies memory and then returns the previous value.- {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, - or an integer whose bit count meets these requirements: -
-- TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe - we can remove this restriction + {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, + an integer or an enum.
Supported operations: @@ -6782,17 +6764,8 @@ async fn func(y: *i32) void { This builtin function atomically stores a value.
- {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, a float, - an integer whose bit count meets these requirements: -
-- TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe - we can remove this restriction + {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, + an integer or an enum.
{#header_close#} {#header_open|@bitCast#} @@ -7108,7 +7081,8 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_v more efficiently in machine instructions.- {#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("builtin").AtomicOrder{#endsyntax#}. + {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, + an integer or an enum.
{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}
{#see_also|Compile Variables|cmpxchgWeak#} @@ -7136,7 +7110,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val However if you need a stronger guarantee, use {#link|@cmpxchgStrong#}.- {#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("builtin").AtomicOrder{#endsyntax#}. + {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, + an integer or an enum.
{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}
{#see_also|Compile Variables|cmpxchgStrong#} diff --git a/src/codegen.cpp b/src/codegen.cpp index cfb3de292a..66cf919d88 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5229,8 +5229,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I // operand needs widening and truncating ptr_val = LLVMBuildBitCast(g->builder, ptr_val, LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); - cmp_val = LLVMConstZExt(cmp_val, get_llvm_type(g, instruction->actual_type)); - new_val = LLVMConstZExt(new_val, get_llvm_type(g, instruction->actual_type)); + cmp_val = LLVMBuildZExt(g->builder, cmp_val, get_llvm_type(g, instruction->actual_type), ""); + new_val = LLVMBuildZExt(g->builder, new_val, get_llvm_type(g, instruction->actual_type), ""); } LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order); @@ -5846,7 +5846,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable // operand needs widening and truncating LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); - LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, get_llvm_type(g, instruction->actual_type), ""); + LLVMValueRef casted_operand = LLVMBuildZExt(g->builder, operand, get_llvm_type(g, instruction->actual_type), ""); LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, g->is_single_threaded); return LLVMBuildTrunc(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); @@ -5893,10 +5893,10 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab LLVMValueRef value = ir_llvm_value(g, instruction->value); if (instruction->actual_type != nullptr) { - // operand needs widening and truncating + // operand needs widening ptr = LLVMBuildBitCast(g->builder, ptr, LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); - value = LLVMConstZExt(value, get_llvm_type(g, instruction->actual_type)); + value = LLVMBuildZExt(g->builder, value, get_llvm_type(g, instruction->actual_type), ""); } LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type); LLVMSetOrdering(store_inst, ordering); diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig index 9c75afc369..c655bfe7a4 100644 --- a/test/stage1/behavior/atomics.zig +++ b/test/stage1/behavior/atomics.zig @@ -167,7 +167,7 @@ fn testAtomicRmwFloat() void { test "atomics with different types" { testAtomicsWithType(bool, true, false); - inline for (.{ u1, i5, u33 }) |T| { + inline for (.{ u1, i5, u15 }) |T| { var x: T = 0; testAtomicsWithType(T, 0, 1); } @@ -175,8 +175,7 @@ test "atomics with different types" { testAtomicsWithType(i0, 0, 0); } -// a and b souldn't need to be comptime -fn testAtomicsWithType(comptime T: type, comptime a: T, comptime b: T) void { +fn testAtomicsWithType(comptime T: type, a: T, b: T) void { var x: T = b; @atomicStore(T, &x, a, .SeqCst); expect(x == a);