diff --git a/src/Sema.zig b/src/Sema.zig index f53dbea90c..990aa4ddf0 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -7803,6 +7803,10 @@ fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile else => {}, } + if (try sema.typeHasOnePossibleValue(block, elem_ty_src, elem_ty)) |val| { + return sema.addConstant(elem_ty, val); + } + if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { if (try ptr_val.pointerDeref(sema.arena)) |elem_val| { return sema.addConstant(elem_ty, elem_val); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 2e835260af..2f703e2d68 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -541,17 +541,21 @@ pub const DeclGen = struct { defer self.gpa.free(fn_param_types); zig_fn_type.fnParamTypes(fn_param_types); - const llvm_param = try self.gpa.alloc(*const llvm.Type, fn_param_len); - defer self.gpa.free(llvm_param); + const llvm_param_buffer = try self.gpa.alloc(*const llvm.Type, fn_param_len); + defer self.gpa.free(llvm_param_buffer); - for (fn_param_types) |fn_param, i| { - llvm_param[i] = try self.llvmType(fn_param); + var llvm_params_len: c_uint = 0; + for (fn_param_types) |fn_param| { + if (fn_param.hasCodeGenBits()) { + llvm_param_buffer[llvm_params_len] = try self.llvmType(fn_param); + llvm_params_len += 1; + } } const fn_type = llvm.functionType( try self.llvmType(return_type), - llvm_param.ptr, - @intCast(c_uint, fn_param_len), + llvm_param_buffer.ptr, + llvm_params_len, .False, ); const llvm_fn = self.llvmModule().addFunction(decl.name, fn_type); diff --git a/src/type.zig b/src/type.zig index 122faefbc7..c2dc150347 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1822,6 +1822,7 @@ pub const Type = extern union { .int_signed, .int_unsigned => { const bits: u16 = self.cast(Payload.Bits).?.data; + if (bits == 0) return 0; return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8); }, diff --git a/test/behavior.zig b/test/behavior.zig index 10d666f6a4..ebf3fff83f 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -23,7 +23,6 @@ test { _ = @import("behavior/asm.zig"); _ = @import("behavior/async_fn.zig"); } - _ = @import("behavior/atomics_stage1.zig"); _ = @import("behavior/await_struct.zig"); _ = @import("behavior/bit_shifting.zig"); _ = @import("behavior/bitcast.zig"); diff --git a/test/behavior/atomics.zig b/test/behavior/atomics.zig index 14e0933c52..b22183bdbd 100644 --- a/test/behavior/atomics.zig +++ b/test/behavior/atomics.zig @@ -195,3 +195,27 @@ fn testAtomicRmwInt() !void { _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst); try expect(x == 1); } + +test "atomics with different types" { + try testAtomicsWithType(bool, true, false); + + try testAtomicsWithType(u1, 0, 1); + try testAtomicsWithType(i4, 0, 1); + try testAtomicsWithType(u5, 0, 1); + try testAtomicsWithType(i15, 0, 1); + try testAtomicsWithType(u24, 0, 1); + + try testAtomicsWithType(u0, 0, 0); + try testAtomicsWithType(i0, 0, 0); +} + +fn testAtomicsWithType(comptime T: type, a: T, b: T) !void { + var x: T = b; + @atomicStore(T, &x, a, .SeqCst); + try expect(x == a); + try expect(@atomicLoad(T, &x, .SeqCst) == a); + try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a); + try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null); + if (@sizeOf(T) != 0) + try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a); +} diff --git a/test/behavior/atomics_stage1.zig b/test/behavior/atomics_stage1.zig deleted file mode 100644 index f37d1dc8c1..0000000000 --- a/test/behavior/atomics_stage1.zig +++ /dev/null @@ -1,28 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; -const expectEqual = std.testing.expectEqual; -const builtin = @import("builtin"); - -test "atomics with different types" { - try testAtomicsWithType(bool, true, false); - - try testAtomicsWithType(u1, 0, 1); - try testAtomicsWithType(i4, 0, 1); - try testAtomicsWithType(u5, 0, 1); - try testAtomicsWithType(i15, 0, 1); - try testAtomicsWithType(u24, 0, 1); - - try testAtomicsWithType(u0, 0, 0); - try testAtomicsWithType(i0, 0, 0); -} - -fn testAtomicsWithType(comptime T: type, a: T, b: T) !void { - var x: T = b; - @atomicStore(T, &x, a, .SeqCst); - try expect(x == a); - try expect(@atomicLoad(T, &x, .SeqCst) == a); - try expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a); - try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null); - if (@sizeOf(T) != 0) - try expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a); -}