Skip to content

Commit f7e045c

Browse files
committed
Merge pull request #23256 from xtexx/fix-gh-20113
x86_64: fix packedStore miscomp by spilling EFLAGS
2 parents 6705cbd + a26f176 commit f7e045c

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/arch/x86_64/CodeGen.zig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88178,12 +88178,15 @@ fn airStore(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
8817888178
const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
8817988179
defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
8818088180

88181+
const ptr_ty = self.typeOf(bin_op.lhs);
88182+
const ptr_info = ptr_ty.ptrInfo(zcu);
88183+
const is_packed = ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0;
88184+
if (is_packed) try self.spillEflagsIfOccupied();
88185+
8818188186
const src_mcv = try self.resolveInst(bin_op.rhs);
8818288187
const ptr_mcv = try self.resolveInst(bin_op.lhs);
88183-
const ptr_ty = self.typeOf(bin_op.lhs);
8818488188

88185-
const ptr_info = ptr_ty.ptrInfo(zcu);
88186-
if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) {
88189+
if (is_packed) {
8818788190
try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
8818888191
} else {
8818988192
try self.store(ptr_ty, ptr_mcv, src_mcv, .{ .safety = safety });

test/behavior/packed-struct.zig

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,3 +1349,31 @@ test "byte-aligned packed relocation" {
13491349
try expect(S.packed_value.x == 111);
13501350
try expect(S.packed_value.y == &S.global);
13511351
}
1352+
1353+
test "packed struct store of comparison result" {
1354+
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1355+
1356+
const S1 = packed struct {
1357+
val1: u3,
1358+
val2: u3,
1359+
};
1360+
const S2 = packed struct {
1361+
a: bool,
1362+
b: bool,
1363+
};
1364+
1365+
var A: S1 = .{ .val1 = 1, .val2 = 1 };
1366+
A.val2 += 1;
1367+
try expectEqual(1, A.val1);
1368+
try expectEqual(2, A.val2);
1369+
try expect((A.val2 & 1) != 1);
1370+
const result1: S2 = .{ .a = (A.val2 & 1) != 1, .b = (A.val1 & 1) != 1 };
1371+
try expect(result1.a);
1372+
try expect(!result1.b);
1373+
1374+
try expect((A.val2 == 3) == false);
1375+
try expect((A.val2 == 2) == true);
1376+
const result2: S2 = .{ .a = !(A.val2 == 3), .b = (A.val1 == 2) };
1377+
try expect(result2.a);
1378+
try expect(!result2.b);
1379+
}

0 commit comments

Comments
 (0)