| ... | @@ -4917,7 +4917,7 @@ pub const FuncGen = struct { | ... | @@ -4917,7 +4917,7 @@ pub const FuncGen = struct { |
| 4917 | .int_from_float_optimized => try self.airIntFromFloat(inst, .fast), | 4917 | .int_from_float_optimized => try self.airIntFromFloat(inst, .fast), |
| 4918 | | 4918 | |
| 4919 | .array_to_slice => try self.airArrayToSlice(inst), | 4919 | .array_to_slice => try self.airArrayToSlice(inst), |
| 4920 | .float_from_int => try self.airFloatFromInt(inst), | 4920 | .float_from_int => try self.airFloatFromInt(inst), |
| 4921 | .cmpxchg_weak => try self.airCmpxchg(inst, .weak), | 4921 | .cmpxchg_weak => try self.airCmpxchg(inst, .weak), |
| 4922 | .cmpxchg_strong => try self.airCmpxchg(inst, .strong), | 4922 | .cmpxchg_strong => try self.airCmpxchg(inst, .strong), |
| 4923 | .fence => try self.airFence(inst), | 4923 | .fence => try self.airFence(inst), |
| ... | @@ -5955,9 +5955,28 @@ pub const FuncGen = struct { | ... | @@ -5955,9 +5955,28 @@ pub const FuncGen = struct { |
| 5955 | const mod = o.module; | 5955 | const mod = o.module; |
| 5956 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5956 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5957 | | 5957 | |
| 5958 | const operand = try self.resolveInst(ty_op.operand); | 5958 | const workaround_operand = try self.resolveInst(ty_op.operand); |
| 5959 | const operand_ty = self.typeOf(ty_op.operand); | 5959 | const operand_ty = self.typeOf(ty_op.operand); |
| 5960 | const operand_scalar_ty = operand_ty.scalarType(mod); | 5960 | const operand_scalar_ty = operand_ty.scalarType(mod); |
| | 5961 | const is_signed_int = operand_scalar_ty.isSignedInt(mod); |
| | 5962 | |
| | 5963 | const operand = o: { |
| | 5964 | // Work around LLVM bug. See https://github.com/ziglang/zig/issues/17381. |
| | 5965 | const bit_size = operand_scalar_ty.bitSize(mod); |
| | 5966 | for ([_]u8{ 8, 16, 32, 64, 128 }) |b| { |
| | 5967 | if (bit_size < b) { |
| | 5968 | break :o try self.wip.cast( |
| | 5969 | if (is_signed_int) .sext else .zext, |
| | 5970 | workaround_operand, |
| | 5971 | try o.builder.intType(b), |
| | 5972 | "", |
| | 5973 | ); |
| | 5974 | } else if (bit_size == b) { |
| | 5975 | break :o workaround_operand; |
| | 5976 | } |
| | 5977 | } |
| | 5978 | break :o workaround_operand; |
| | 5979 | }; |
| 5961 | | 5980 | |
| 5962 | const dest_ty = self.typeOfIndex(inst); | 5981 | const dest_ty = self.typeOfIndex(inst); |
| 5963 | const dest_scalar_ty = dest_ty.scalarType(mod); | 5982 | const dest_scalar_ty = dest_ty.scalarType(mod); |
| ... | @@ -5965,7 +5984,7 @@ pub const FuncGen = struct { | ... | @@ -5965,7 +5984,7 @@ pub const FuncGen = struct { |
| 5965 | const target = mod.getTarget(); | 5984 | const target = mod.getTarget(); |
| 5966 | | 5985 | |
| 5967 | if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv( | 5986 | if (intrinsicsAllowed(dest_scalar_ty, target)) return self.wip.conv( |
| 5968 | if (operand_scalar_ty.isSignedInt(mod)) .signed else .unsigned, | 5987 | if (is_signed_int) .signed else .unsigned, |
| 5969 | operand, | 5988 | operand, |
| 5970 | dest_llvm_ty, | 5989 | dest_llvm_ty, |
| 5971 | "", | 5990 | "", |
| ... | @@ -5974,7 +5993,7 @@ pub const FuncGen = struct { | ... | @@ -5974,7 +5993,7 @@ pub const FuncGen = struct { |
| 5974 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(mod))); | 5993 | const rt_int_bits = compilerRtIntBits(@intCast(operand_scalar_ty.bitSize(mod))); |
| 5975 | const rt_int_ty = try o.builder.intType(rt_int_bits); | 5994 | const rt_int_ty = try o.builder.intType(rt_int_bits); |
| 5976 | var extended = try self.wip.conv( | 5995 | var extended = try self.wip.conv( |
| 5977 | if (operand_scalar_ty.isSignedInt(mod)) .signed else .unsigned, | 5996 | if (is_signed_int) .signed else .unsigned, |
| 5978 | operand, | 5997 | operand, |
| 5979 | rt_int_ty, | 5998 | rt_int_ty, |
| 5980 | "", | 5999 | "", |
| ... | @@ -5982,7 +6001,7 @@ pub const FuncGen = struct { | ... | @@ -5982,7 +6001,7 @@ pub const FuncGen = struct { |
| 5982 | const dest_bits = dest_scalar_ty.floatBits(target); | 6001 | const dest_bits = dest_scalar_ty.floatBits(target); |
| 5983 | const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits); | 6002 | const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits); |
| 5984 | const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits); | 6003 | const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits); |
| 5985 | const sign_prefix = if (operand_scalar_ty.isSignedInt(mod)) "" else "un"; | 6004 | const sign_prefix = if (is_signed_int) "" else "un"; |
| 5986 | const fn_name = try o.builder.fmt("__float{s}{s}i{s}f", .{ | 6005 | const fn_name = try o.builder.fmt("__float{s}{s}i{s}f", .{ |
| 5987 | sign_prefix, | 6006 | sign_prefix, |
| 5988 | compiler_rt_operand_abbrev, | 6007 | compiler_rt_operand_abbrev, |