mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 19:23:08 +00:00
stage2: improve handling of 0 bit types
* Sema: zirAtomicLoad handles 0-bit types correctly * LLVM backend: when lowering function types, elide parameters with 0-bit types. * Type: abiSize handles u0/i0 correctly
This commit is contained in:
parent
4b2d7a9c67
commit
abc30f7948
@ -7803,6 +7803,10 @@ fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
|
|||||||
else => {},
|
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 sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
|
||||||
if (try ptr_val.pointerDeref(sema.arena)) |elem_val| {
|
if (try ptr_val.pointerDeref(sema.arena)) |elem_val| {
|
||||||
return sema.addConstant(elem_ty, elem_val);
|
return sema.addConstant(elem_ty, elem_val);
|
||||||
|
|||||||
@ -541,17 +541,21 @@ pub const DeclGen = struct {
|
|||||||
defer self.gpa.free(fn_param_types);
|
defer self.gpa.free(fn_param_types);
|
||||||
zig_fn_type.fnParamTypes(fn_param_types);
|
zig_fn_type.fnParamTypes(fn_param_types);
|
||||||
|
|
||||||
const llvm_param = try self.gpa.alloc(*const llvm.Type, fn_param_len);
|
const llvm_param_buffer = try self.gpa.alloc(*const llvm.Type, fn_param_len);
|
||||||
defer self.gpa.free(llvm_param);
|
defer self.gpa.free(llvm_param_buffer);
|
||||||
|
|
||||||
for (fn_param_types) |fn_param, i| {
|
var llvm_params_len: c_uint = 0;
|
||||||
llvm_param[i] = try self.llvmType(fn_param);
|
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(
|
const fn_type = llvm.functionType(
|
||||||
try self.llvmType(return_type),
|
try self.llvmType(return_type),
|
||||||
llvm_param.ptr,
|
llvm_param_buffer.ptr,
|
||||||
@intCast(c_uint, fn_param_len),
|
llvm_params_len,
|
||||||
.False,
|
.False,
|
||||||
);
|
);
|
||||||
const llvm_fn = self.llvmModule().addFunction(decl.name, fn_type);
|
const llvm_fn = self.llvmModule().addFunction(decl.name, fn_type);
|
||||||
|
|||||||
@ -1822,6 +1822,7 @@ pub const Type = extern union {
|
|||||||
|
|
||||||
.int_signed, .int_unsigned => {
|
.int_signed, .int_unsigned => {
|
||||||
const bits: u16 = self.cast(Payload.Bits).?.data;
|
const bits: u16 = self.cast(Payload.Bits).?.data;
|
||||||
|
if (bits == 0) return 0;
|
||||||
return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
|
return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@ test {
|
|||||||
_ = @import("behavior/asm.zig");
|
_ = @import("behavior/asm.zig");
|
||||||
_ = @import("behavior/async_fn.zig");
|
_ = @import("behavior/async_fn.zig");
|
||||||
}
|
}
|
||||||
_ = @import("behavior/atomics_stage1.zig");
|
|
||||||
_ = @import("behavior/await_struct.zig");
|
_ = @import("behavior/await_struct.zig");
|
||||||
_ = @import("behavior/bit_shifting.zig");
|
_ = @import("behavior/bit_shifting.zig");
|
||||||
_ = @import("behavior/bitcast.zig");
|
_ = @import("behavior/bitcast.zig");
|
||||||
|
|||||||
@ -195,3 +195,27 @@ fn testAtomicRmwInt() !void {
|
|||||||
_ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
|
_ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
|
||||||
try expect(x == 1);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user