Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,428 changes: 1,200 additions & 228 deletions src/Air/Legalize.zig

Large diffs are not rendered by default.

34 changes: 24 additions & 10 deletions src/Type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1636,14 +1636,22 @@ pub fn bitSizeInner(
.array_type => |array_type| {
const len = array_type.lenIncludingSentinel();
if (len == 0) return 0;
const elem_ty = Type.fromInterned(array_type.child);
const elem_size = (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar;
if (elem_size == 0) return 0;
const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
return (len - 1) * 8 * elem_size + elem_bit_size;
const elem_ty: Type = .fromInterned(array_type.child);
switch (zcu.comp.getZigBackend()) {
else => {
const elem_size = (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar;
if (elem_size == 0) return 0;
const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
return (len - 1) * 8 * elem_size + elem_bit_size;
},
.stage2_x86_64 => {
const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
return elem_bit_size * len;
},
}
},
.vector_type => |vector_type| {
const child_ty = Type.fromInterned(vector_type.child);
const child_ty: Type = .fromInterned(vector_type.child);
const elem_bit_size = try child_ty.bitSizeInner(strat, zcu, tid);
return elem_bit_size * vector_type.len;
},
Expand Down Expand Up @@ -3549,10 +3557,16 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
running_bits += @intCast(f_ty.bitSize(zcu));
}

const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0)
.{ parent_ptr_info.packed_offset.host_size, parent_ptr_info.packed_offset.bit_offset + bit_offset }
else
.{ (running_bits + 7) / 8, bit_offset };
const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0) .{
parent_ptr_info.packed_offset.host_size,
parent_ptr_info.packed_offset.bit_offset + bit_offset,
} else .{
switch (zcu.comp.getZigBackend()) {
else => (running_bits + 7) / 8,
.stage2_x86_64 => @intCast(struct_ty.abiSize(zcu)),
},
bit_offset,
};

// If the field happens to be byte-aligned, simplify the pointer type.
// We can only do this if the pointee's bit size matches its ABI byte size,
Expand Down
7 changes: 7 additions & 0 deletions src/arch/x86_64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features
.scalarize_shl_sat = true,
.scalarize_xor = use_old,
.scalarize_not = use_old,
.scalarize_bitcast = true,
.scalarize_clz = use_old,
.scalarize_ctz = true,
.scalarize_popcount = true,
Expand Down Expand Up @@ -99,10 +100,16 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features

.unsplat_shift_rhs = false,
.reduce_one_elem_to_bitcast = true,

.expand_intcast_safe = true,
.expand_add_safe = true,
.expand_sub_safe = true,
.expand_mul_safe = true,

.expand_packed_load = true,
.expand_packed_store = true,
.expand_packed_struct_field_val = true,
.expand_packed_aggregate_init = true,
}),
};
}
Expand Down
2 changes: 1 addition & 1 deletion test/behavior.zig
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ test {

_ = @import("behavior/x86_64.zig");

if (builtin.zig_backend != .stage2_spirv64 and builtin.cpu.arch == .wasm32) {
if (builtin.cpu.arch == .wasm32) {
_ = @import("behavior/wasm.zig");
}

Expand Down
16 changes: 8 additions & 8 deletions test/behavior/align.zig
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,10 @@ test "sub-aligned pointer field access" {
}

test "alignment of zero-bit types is respected" {
if (true) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;

const S = struct { arr: [0]usize = .{} };

Expand Down Expand Up @@ -598,11 +601,8 @@ test "function pointer @intFromPtr/@ptrFromInt roundtrip" {
}

test "function pointer align mask" {
if (!(builtin.cpu.arch.isArm() or builtin.cpu.arch.isMIPS())) return error.SkipZigTest;

const a: *const fn () callconv(.c) void = @ptrFromInt(0x20202021);
_ = &a;

const b: *align(16) const fn () callconv(.c) void = @alignCast(a);
_ = &b;
const int = if (builtin.cpu.arch.isArm() or builtin.cpu.arch.isMIPS()) 0x20202021 else 0x20202020;
const unaligned: *const fn () callconv(.c) void = @ptrFromInt(int);
const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned);
try expect(@intFromPtr(aligned) == int);
}
2 changes: 1 addition & 1 deletion test/behavior/bitcast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ test "comptime @bitCast packed struct to int and back" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;

const S = packed struct {
void: void = {},
Expand Down
1 change: 0 additions & 1 deletion test/behavior/cast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2610,7 +2610,6 @@ test "@intFromBool on vector" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;

const S = struct {
fn doTheTest() !void {
Expand Down
2 changes: 1 addition & 1 deletion test/behavior/struct.zig
Original file line number Diff line number Diff line change
Expand Up @@ -559,9 +559,9 @@ test "packed struct with non-ABI-aligned field" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;

const S = packed struct {
x: u9,
Expand Down
10 changes: 7 additions & 3 deletions test/behavior/union.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1607,9 +1607,13 @@ test "packed union field pointer has correct alignment" {
const bp = &b.u.x;
const cp = &c.u.x;

comptime assert(@TypeOf(ap) == *align(4:2:3) u20);
comptime assert(@TypeOf(bp) == *align(1:2:3) u20);
comptime assert(@TypeOf(cp) == *align(64:2:3) u20);
const host_size = switch (builtin.zig_backend) {
else => comptime std.math.divCeil(comptime_int, @bitSizeOf(S), 8) catch unreachable,
.stage2_x86_64 => @sizeOf(S),
};
comptime assert(@TypeOf(ap) == *align(4:2:host_size) u20);
comptime assert(@TypeOf(bp) == *align(1:2:host_size) u20);
comptime assert(@TypeOf(cp) == *align(64:2:host_size) u20);

a.u = .{ .x = 123 };
b.u = .{ .x = 456 };
Expand Down
Loading