mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #23256 from xtexx/fix-gh-20113
x86_64: fix packedStore miscomp by spilling EFLAGS
This commit is contained in:
commit
f7e045c806
@ -88178,12 +88178,15 @@ fn airStore(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
|
||||
const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
|
||||
defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
|
||||
|
||||
const ptr_ty = self.typeOf(bin_op.lhs);
|
||||
const ptr_info = ptr_ty.ptrInfo(zcu);
|
||||
const is_packed = ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0;
|
||||
if (is_packed) try self.spillEflagsIfOccupied();
|
||||
|
||||
const src_mcv = try self.resolveInst(bin_op.rhs);
|
||||
const ptr_mcv = try self.resolveInst(bin_op.lhs);
|
||||
const ptr_ty = self.typeOf(bin_op.lhs);
|
||||
|
||||
const ptr_info = ptr_ty.ptrInfo(zcu);
|
||||
if (ptr_info.flags.vector_index != .none or ptr_info.packed_offset.host_size > 0) {
|
||||
if (is_packed) {
|
||||
try self.packedStore(ptr_ty, ptr_mcv, src_mcv);
|
||||
} else {
|
||||
try self.store(ptr_ty, ptr_mcv, src_mcv, .{ .safety = safety });
|
||||
|
||||
@ -1349,3 +1349,31 @@ test "byte-aligned packed relocation" {
|
||||
try expect(S.packed_value.x == 111);
|
||||
try expect(S.packed_value.y == &S.global);
|
||||
}
|
||||
|
||||
test "packed struct store of comparison result" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S1 = packed struct {
|
||||
val1: u3,
|
||||
val2: u3,
|
||||
};
|
||||
const S2 = packed struct {
|
||||
a: bool,
|
||||
b: bool,
|
||||
};
|
||||
|
||||
var A: S1 = .{ .val1 = 1, .val2 = 1 };
|
||||
A.val2 += 1;
|
||||
try expectEqual(1, A.val1);
|
||||
try expectEqual(2, A.val2);
|
||||
try expect((A.val2 & 1) != 1);
|
||||
const result1: S2 = .{ .a = (A.val2 & 1) != 1, .b = (A.val1 & 1) != 1 };
|
||||
try expect(result1.a);
|
||||
try expect(!result1.b);
|
||||
|
||||
try expect((A.val2 == 3) == false);
|
||||
try expect((A.val2 == 2) == true);
|
||||
const result2: S2 = .{ .a = !(A.val2 == 3), .b = (A.val1 == 2) };
|
||||
try expect(result2.a);
|
||||
try expect(!result2.b);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user