| ... | ... | @@ -10078,13 +10078,21 @@ fn intCast( |
| 10078 | 10078 | if (actual_info.signedness == .signed) { |
| 10079 | 10079 | // Reinterpret the sign-bit as part of the value. This will make |
| 10080 | 10080 | // negative differences (`operand` > `dest_max`) appear too big. |
| 10081 | | const unsigned_operand_ty = try mod.intType(.unsigned, actual_bits); |
| 10081 | const unsigned_scalar_operand_ty = try mod.intType(.unsigned, actual_bits); |
| 10082 | const unsigned_operand_ty = if (is_vector) try mod.vectorType(.{ |
| 10083 | .len = dest_ty.vectorLen(mod), |
| 10084 | .child = unsigned_scalar_operand_ty.toIntern(), |
| 10085 | }) else unsigned_scalar_operand_ty; |
| 10082 | 10086 | const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff); |
| 10083 | 10087 | |
| 10084 | 10088 | // If the destination type is signed, then we need to double its |
| 10085 | 10089 | // range to account for negative values. |
| 10086 | 10090 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { |
| 10087 | | const one = try mod.intValue(unsigned_operand_ty, 1); |
| 10091 | const one_scalar = try mod.intValue(unsigned_scalar_operand_ty, 1); |
| 10092 | const one = if (is_vector) (try mod.intern(.{ .aggregate = .{ |
| 10093 | .ty = unsigned_operand_ty.toIntern(), |
| 10094 | .storage = .{ .repeated_elem = one_scalar.toIntern() }, |
| 10095 | } })).toValue() else one_scalar; |
| 10088 | 10096 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod); |
| 10089 | 10097 | break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty, undefined); |
| 10090 | 10098 | } else try mod.getCoerced(dest_max_val, unsigned_operand_ty); |