authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-02 13:50:50-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-03 22:28:39+02:00
log3391ad7a9091edec0b368b0e98e61ec02043e91b
tree20dd8e738a7abe22e9807a4561b75de4f9ca2c96
parent22aa2bd1e775d5ec144711642ad5c0d7c99b4398

x86_64: implement and test `@intFromBool`

Also fixes, for the x86_64 backend, #31963

3 files changed, 31 insertions(+), 3 deletions(-)

src/Air/print.zig-1
......@@ -516,7 +516,6 @@ const Writer = struct {
516516 try w.writeOperand(s, inst, 1, bin.lhs);
517517 try s.writeAll(", ");
518518 try w.writeOperand(s, inst, 2, bin.rhs);
519 try s.writeAll(", ");
520519 }
521520
522521 fn writeLegalizeCompilerRtCall(w: *Writer, s: *std.Io.Writer, inst: Air.Inst.Index) Error!void {
src/codegen/x86_64/CodeGen.zig+21-2
......@@ -179453,7 +179453,26 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void {
179453179453 .gt => src_ty,
179454179454 },
179455179455 .register_mask => src_ty,
179456 }, dst_mcv, src_mcv, .{});
179456 }, dst_mcv, if (src_ty.isVector(zcu) and src_ty.childType(zcu).toIntern() == .bool_type) src_mcv: {
179457 try self.spillEflagsIfOccupied();
179458 const dst_signedness: std.builtin.Signedness = if (dst_ty.scalarType(zcu).isSignedInt(zcu)) .signed else .unsigned;
179459 switch (src_mcv) {
179460 .immediate => |src_imm| break :src_mcv .{ .immediate = switch (dst_signedness) {
179461 .unsigned => @as(u1, @truncate(src_imm)),
179462 .signed => @as(u8, @bitCast(@as(i8, @as(i1, @bitCast(@as(u1, @truncate(src_imm))))))),
179463 } },
179464 else => {
179465 try self.spillEflagsIfOccupied();
179466 const tmp_reg = try self.copyToTmpRegister(.u8, src_mcv);
179467 try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp_reg.to8(), .u(1));
179468 switch (dst_signedness) {
179469 .unsigned => {},
179470 .signed => try self.asmRegister(.{ ._, .neg }, tmp_reg.to8()),
179471 }
179472 break :src_mcv .{ .register = tmp_reg };
179473 },
179474 }
179475 } else src_mcv, .{});
179457179476 break :dst dst_mcv;
179458179477 };
179459179478
......@@ -182778,7 +182797,7 @@ const Temp = struct {
182778182797 break :part_ty .usize;
182779182798 },
182780182799 },
182781 .struct_type => {
182800 .struct_type, .union_type => {
182782182801 assert(src_regs.len - part_index == std.math.divCeil(u32, src_abi_size, 8) catch unreachable);
182783182802 break :part_ty switch (src_abi_size) {
182784182803 0, 3, 5...7 => unreachable,
test/behavior/x86_64/unary.zig+10
......@@ -1,5 +1,6 @@
11const AsSignedness = math.AsSignedness;
22const checkExpected = math.checkExpected;
3const ChangeScalar = math.ChangeScalar;
34const Compare = math.Compare;
45const fmax = math.fmax;
56const fmin = math.fmin;
......@@ -4890,6 +4891,15 @@ test bitNot {
48904891 try test_bit_not.testIntVectors();
48914892}
48924893
4894inline fn intFromBool(comptime Type: type, rhs: Type) ChangeScalar(Type, u1) {
4895 return @intFromBool(rhs);
4896}
4897test intFromBool {
4898 const test_int_from_bool = unary(intFromBool, .{});
4899 try test_int_from_bool.testBools();
4900 try test_int_from_bool.testBoolVectors();
4901}
4902
48934903inline fn clz(comptime Type: type, rhs: Type) Log2IntCeil(Type) {
48944904 return @clz(rhs);
48954905}