Skip to content

Commit dc1583b

Browse files
committed
x86_64: fix packedStore miscomp by spilling EFLAGS
Fixes #20113. First, postpone operand resolve from airStore into packedStore/store. Then, spill EFLAGS before AND in packedStore as AND instructions clobber EFLAGS, which may break EFLAGS operands. Bug: #20113 Signed-off-by: Bingwu Zhang <[email protected]>
1 parent 11b49e9 commit dc1583b

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

src/arch/x86_64/CodeGen.zig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88054,6 +88054,8 @@ fn packedStore(self: *CodeGen, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue)
8805488054
const part_mask = (@as(u64, std.math.maxInt(u64)) >> @intCast(64 - part_bit_size)) <<
8805588055
@intCast(part_bit_off);
8805688056
const part_mask_not = part_mask ^ (@as(u64, std.math.maxInt(u64)) >> @intCast(64 - limb_abi_bits));
88057+
// AND clobbers EFLAGS
88058+
try self.spillEflagsIfOccupied();
8805788059
if (limb_abi_size <= 4) {
8805888060
try self.asmMemoryImmediate(.{ ._, .@"and" }, limb_mem, .u(part_mask_not));
8805988061
} else if (std.math.cast(i32, @as(i64, @bitCast(part_mask_not)))) |small| {
@@ -88178,8 +88180,8 @@ fn airStore(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
8817888180
const reg_locks = self.register_manager.lockRegsAssumeUnused(3, .{ .rdi, .rsi, .rcx });
8817988181
defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
8818088182

88181-
const src_mcv = try self.resolveInst(bin_op.rhs);
88182-
const ptr_mcv = try self.resolveInst(bin_op.lhs);
88183+
const src_mcv = MCValue{ .air_ref = bin_op.rhs };
88184+
const ptr_mcv = MCValue{ .air_ref = bin_op.lhs };
8818388185
const ptr_ty = self.typeOf(bin_op.lhs);
8818488186

8818588187
const ptr_info = ptr_ty.ptrInfo(zcu);

0 commit comments

Comments
 (0)