diff --git a/src/Air/print.zig b/src/Air/print.zig index 70e5a9308424e781a54a1fc8c8a23ac075940d17..b3739ece3334ede99c3d66164b9fdbd3b7dfec54 100644 --- a/src/Air/print.zig +++ b/src/Air/print.zig @@ -516,7 +516,6 @@ const Writer = struct { try w.writeOperand(s, inst, 1, bin.lhs); try s.writeAll(", "); try w.writeOperand(s, inst, 2, bin.rhs); - try s.writeAll(", "); } fn writeLegalizeCompilerRtCall(w: *Writer, s: *std.Io.Writer, inst: Air.Inst.Index) Error!void { diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig index 3074e51fc12f1543636f2795c72891ae7761b2ee..821aaf50270149896b83619c82e1989678d98be9 100644 --- a/src/codegen/x86_64/CodeGen.zig +++ b/src/codegen/x86_64/CodeGen.zig @@ -179453,7 +179453,26 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void { .gt => src_ty, }, .register_mask => src_ty, - }, dst_mcv, src_mcv, .{}); + }, dst_mcv, if (src_ty.isVector(zcu) and src_ty.childType(zcu).toIntern() == .bool_type) src_mcv: { + try self.spillEflagsIfOccupied(); + const dst_signedness: std.builtin.Signedness = if (dst_ty.scalarType(zcu).isSignedInt(zcu)) .signed else .unsigned; + switch (src_mcv) { + .immediate => |src_imm| break :src_mcv .{ .immediate = switch (dst_signedness) { + .unsigned => @as(u1, @truncate(src_imm)), + .signed => @as(u8, @bitCast(@as(i8, @as(i1, @bitCast(@as(u1, @truncate(src_imm))))))), + } }, + else => { + try self.spillEflagsIfOccupied(); + const tmp_reg = try self.copyToTmpRegister(.u8, src_mcv); + try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp_reg.to8(), .u(1)); + switch (dst_signedness) { + .unsigned => {}, + .signed => try self.asmRegister(.{ ._, .neg }, tmp_reg.to8()), + } + break :src_mcv .{ .register = tmp_reg }; + }, + } + } else src_mcv, .{}); break :dst dst_mcv; }; @@ -182778,7 +182797,7 @@ const Temp = struct { break :part_ty .usize; }, }, - .struct_type => { + .struct_type, .union_type => { assert(src_regs.len - part_index == std.math.divCeil(u32, src_abi_size, 8) catch unreachable); break :part_ty switch (src_abi_size) { 0, 3, 5...7 => unreachable, diff --git a/test/behavior/x86_64/unary.zig b/test/behavior/x86_64/unary.zig index 780682a7aaf6d0aa5d882bd0eaceead4cd16fe23..a8446caae6e0ed7b125e6997eab8601a4253d2e6 100644 --- a/test/behavior/x86_64/unary.zig +++ b/test/behavior/x86_64/unary.zig @@ -1,5 +1,6 @@ const AsSignedness = math.AsSignedness; const checkExpected = math.checkExpected; +const ChangeScalar = math.ChangeScalar; const Compare = math.Compare; const fmax = math.fmax; const fmin = math.fmin; @@ -4890,6 +4891,15 @@ test bitNot { try test_bit_not.testIntVectors(); } +inline fn intFromBool(comptime Type: type, rhs: Type) ChangeScalar(Type, u1) { + return @intFromBool(rhs); +} +test intFromBool { + const test_int_from_bool = unary(intFromBool, .{}); + try test_int_from_bool.testBools(); + try test_int_from_bool.testBoolVectors(); +} + inline fn clz(comptime Type: type, rhs: Type) Log2IntCeil(Type) { return @clz(rhs); }