authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-05-31 23:39:35-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-01 08:24:01+01:00
log6daa37ded905431f3a25508a42590031b0905ab9
tree0b8e5e0a0bf7aff870d07fffb09537d684d75295
parent9edfccb9a7d23dbf02444023d042d5008a39462e
signaturelock-open Commit is signed but in an unrecognized format.

x86_64: fix packed struct equality

Closes #22990

2 files changed, 29 insertions(+), 2 deletions(-)

src/arch/x86_64/CodeGen.zig+18-2
...@@ -77309,11 +77309,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77309,11 +77309,27 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77309 },77309 },
77310 }77310 }
77311 },77311 },
77312 .int => res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err,77312 .int => {
77313 switch (ty.zigTypeTag(zcu)) {
77314 else => {},
77315 .@"struct", .@"union" => {
77316 assert(ty.containerLayout(zcu) == .@"packed");
77317 for (&ops) |*op| op.wrapInt(cg) catch |err| switch (err) {
77318 error.SelectFailed => return cg.fail("failed to select {s} wrap {} {}", .{
77319 @tagName(air_tag),
77320 ty.fmt(pt),
77321 op.tracking(cg),
77322 }),
77323 else => |e| return e,
77324 };
77325 },
77326 }
77327 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
77328 },
77313 }) catch |err| switch (err) {77329 }) catch |err| switch (err) {
77314 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{77330 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
77315 @tagName(air_tag),77331 @tagName(air_tag),
77316 cg.typeOf(bin_op.lhs).fmt(pt),77332 ty.fmt(pt),
77317 ops[0].tracking(cg),77333 ops[0].tracking(cg),
77318 ops[1].tracking(cg),77334 ops[1].tracking(cg),
77319 }),77335 }),
test/behavior/packed-struct.zig+11
...@@ -1307,6 +1307,17 @@ test "packed struct equality" {...@@ -1307,6 +1307,17 @@ test "packed struct equality" {
1307 comptime try S.doTest(x, y);1307 comptime try S.doTest(x, y);
1308}1308}
13091309
1310test "packed struct equality ignores padding bits" {
1311 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1312 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1313
1314 const S = packed struct { b: bool };
1315 var s: S = undefined;
1316 s.b = true;
1317 try std.testing.expect(s != S{ .b = false });
1318 try std.testing.expect(s == S{ .b = true });
1319}
1320
1310test "packed struct with signed field" {1321test "packed struct with signed field" {
1311 var s: packed struct {1322 var s: packed struct {
1312 a: i2,1323 a: i2,