authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-04 21:05:00+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-05 02:16:56-05:00
log941d3a2bb1213b04399fe772aaf88c35d043af01
tree09119d1ed9d2fca69373cf8cc6ce3043733ab1bd
parenteaa6218f09d12fc84a29462f8287c0e6ecfd6739

x86_64: fix miscompilations on baseline


1 files changed, 34 insertions(+), 37 deletions(-)

src/arch/x86_64/CodeGen.zig+34-37
...@@ -5653,10 +5653,10 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -5653,10 +5653,10 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
5653 const dst_lock = self.register_manager.lockReg(dst_reg);5653 const dst_lock = self.register_manager.lockReg(dst_reg);
5654 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);5654 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
56555655
5656 const wide_ty = if (src_bits <= 8) Type.u16 else src_ty;
5656 if (self.hasFeature(.bmi)) {5657 if (self.hasFeature(.bmi)) {
5657 if (src_bits <= 64) {5658 if (src_bits <= 64) {
5658 const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0);5659 const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0);
5659 const wide_ty = if (src_bits <= 8) Type.u16 else src_ty;
5660 const masked_mcv = if (extra_bits > 0) masked: {5660 const masked_mcv = if (extra_bits > 0) masked: {
5661 const tmp_mcv = tmp: {5661 const tmp_mcv = tmp: {
5662 if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0))5662 if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0))
...@@ -5718,7 +5718,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {...@@ -5718,7 +5718,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
5718 defer self.register_manager.unlockReg(wide_lock);5718 defer self.register_manager.unlockReg(wide_lock);
57195719
5720 try self.truncateRegister(src_ty, wide_reg);5720 try self.truncateRegister(src_ty, wide_reg);
5721 try self.genBinOpMir(.{ ._, .bsf }, Type.u16, dst_mcv, .{ .register = wide_reg });5721 try self.genBinOpMir(.{ ._, .bsf }, wide_ty, dst_mcv, .{ .register = wide_reg });
5722 } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv);5722 } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv);
57235723
5724 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2);5724 const cmov_abi_size = @max(@as(u32, @intCast(dst_ty.abiSize(mod))), 2);
...@@ -5890,6 +5890,7 @@ fn genByteSwap(...@@ -5890,6 +5890,7 @@ fn genByteSwap(
5890) !MCValue {5890) !MCValue {
5891 const mod = self.bin_file.comp.module.?;5891 const mod = self.bin_file.comp.module.?;
5892 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5892 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5893 const have_movbe = self.hasFeature(.movbe);
58935894
5894 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail(5895 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail(
5895 "TODO implement genByteSwap for {}",5896 "TODO implement genByteSwap for {}",
...@@ -5935,46 +5936,42 @@ fn genByteSwap(...@@ -5935,46 +5936,42 @@ fn genByteSwap(
5935 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);5936 const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs);
5936 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);5937 defer for (dst_locks) |lock| self.register_manager.unlockReg(lock);
59375938
5938 if (src_mcv.isMemory()) {5939 for (dst_regs, 0..) |dst_reg, limb_index| {
5939 try self.asmRegisterMemory(5940 if (src_mcv.isMemory()) {
5940 .{ ._, .movbe },5941 try self.asmRegisterMemory(
5941 dst_regs[0],5942 .{ ._, if (have_movbe) .movbe else .mov },
5942 try src_mcv.address().offset(8).deref().mem(self, .qword),5943 dst_reg.to64(),
5943 );5944 try src_mcv.address().offset(@intCast(limb_index * 8)).deref().mem(self, .qword),
5944 try self.asmRegisterMemory(.{ ._, .movbe }, dst_regs[1], try src_mcv.mem(self, .qword));5945 );
5945 } else for (dst_regs, src_mcv.register_pair) |dst_reg, src_reg| {5946 if (!have_movbe) try self.asmRegister(.{ ._, .bswap }, dst_reg.to64());
5946 try self.asmRegisterRegister(.{ ._, .mov }, dst_reg.to64(), src_reg.to64());5947 } else {
5947 try self.asmRegister(.{ ._, .bswap }, dst_reg.to64());5948 try self.asmRegisterRegister(
5949 .{ ._, .mov },
5950 dst_reg.to64(),
5951 src_mcv.register_pair[limb_index].to64(),
5952 );
5953 try self.asmRegister(.{ ._, .bswap }, dst_reg.to64());
5954 }
5948 }5955 }
5949 return .{ .register_pair = dst_regs };5956 return .{ .register_pair = .{ dst_regs[1], dst_regs[0] } };
5950 },5957 },
5951 }5958 }
59525959
5953 if (src_mcv.isRegister()) {5960 const dst_mcv: MCValue = if (mem_ok and have_movbe and src_mcv.isRegister())
5954 const dst_mcv: MCValue = if (mem_ok)5961 try self.allocRegOrMem(inst, true)
5955 try self.allocRegOrMem(inst, true)5962 else
5956 else5963 .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.gp) };
5957 .{ .register = try self.register_manager.allocReg(inst, abi.RegisterClass.gp) };5964 if (dst_mcv.getReg()) |dst_reg| {
5958 if (dst_mcv.isRegister()) {5965 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register);
5959 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_mcv.register);5966 defer self.register_manager.unlockReg(dst_lock);
5960 defer self.register_manager.unlockReg(dst_lock);
5961
5962 try self.genSetReg(dst_mcv.register, src_ty, src_mcv);
5963 switch (abi_size) {
5964 else => unreachable,
5965 2 => try self.genBinOpMir(.{ ._l, .ro }, src_ty, dst_mcv, .{ .immediate = 8 }),
5966 3...8 => try self.genUnOpMir(.{ ._, .bswap }, src_ty, dst_mcv),
5967 }
5968 } else try self.genBinOpMir(.{ ._, .movbe }, src_ty, dst_mcv, src_mcv);
5969 return dst_mcv;
5970 }
5971
5972 const dst_reg = try self.register_manager.allocReg(inst, abi.RegisterClass.gp);
5973 const dst_mcv = MCValue{ .register = dst_reg };
5974 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
5975 defer self.register_manager.unlockReg(dst_lock);
59765967
5977 try self.genBinOpMir(.{ ._, .movbe }, src_ty, dst_mcv, src_mcv);5968 try self.genSetReg(dst_reg, src_ty, src_mcv);
5969 switch (abi_size) {
5970 else => unreachable,
5971 2 => try self.genBinOpMir(.{ ._l, .ro }, src_ty, dst_mcv, .{ .immediate = 8 }),
5972 3...8 => try self.genUnOpMir(.{ ._, .bswap }, src_ty, dst_mcv),
5973 }
5974 } else try self.genBinOpMir(.{ ._, .movbe }, src_ty, dst_mcv, src_mcv);
5978 return dst_mcv;5975 return dst_mcv;
5979}5976}
59805977