diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2023-11-06 14:30:34 +0000 |
|---|---|---|
| committer | Matthew Lugg <mlugg@mlugg.co.uk> | 2023-11-07 06:42:15 +0000 |
| commit | d78eda34c5de1ce869c55057b790081012e00bf5 (patch) | |
| tree | 67a02c8190529110b4c516ec528ec2632f43ddf9 /src | |
| parent | 9b394a200a55c8347e32607dcff568e8482ada48 (diff) | |
| download | zig-d78eda34c5de1ce869c55057b790081012e00bf5.tar.gz zig-d78eda34c5de1ce869c55057b790081012e00bf5.zip | |
Sema: emit @intCast safety check correctly for vectors
This code was previously tripping an assertion by not making this value
used in the safety check a vector.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 047f8c2c96..2950f7e405 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10078,13 +10078,21 @@ fn intCast( if (actual_info.signedness == .signed) { // Reinterpret the sign-bit as part of the value. This will make // negative differences (`operand` > `dest_max`) appear too big. - const unsigned_operand_ty = try mod.intType(.unsigned, actual_bits); + const unsigned_scalar_operand_ty = try mod.intType(.unsigned, actual_bits); + const unsigned_operand_ty = if (is_vector) try mod.vectorType(.{ + .len = dest_ty.vectorLen(mod), + .child = unsigned_scalar_operand_ty.toIntern(), + }) else unsigned_scalar_operand_ty; const diff_unsigned = try block.addBitCast(unsigned_operand_ty, diff); // If the destination type is signed, then we need to double its // range to account for negative values. const dest_range_val = if (wanted_info.signedness == .signed) range_val: { - const one = try mod.intValue(unsigned_operand_ty, 1); + const one_scalar = try mod.intValue(unsigned_scalar_operand_ty, 1); + const one = if (is_vector) (try mod.intern(.{ .aggregate = .{ + .ty = unsigned_operand_ty.toIntern(), + .storage = .{ .repeated_elem = one_scalar.toIntern() }, + } })).toValue() else one_scalar; const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod); break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty, undefined); } else try mod.getCoerced(dest_max_val, unsigned_operand_ty); |
