authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-04 04:19:26-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-04 04:19:26-08:00
log9a1608509300fcdf118d82063bbf1481a10ca551
tree0c3b2cdc5f9462c26c9e41edcabc793ce66970e2
parent537e2808e04fc34bb2015433895a57c15118eb28
parent52ebba6bdf5662353ce11a701a3361cc0616c01c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18376 from amp-59/shl_exact_comptime_int_to_shl

Sema: Updated `zirShl` to compute `shl_exact` with `comptime_int` LHS using `shl`

3 files changed, 12 insertions(+), 17 deletions(-)

doc/langref.html.in+5
...@@ -9163,6 +9163,11 @@ test "@setRuntimeSafety" {...@@ -9163,6 +9163,11 @@ test "@setRuntimeSafety" {
9163 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).Int.bits){#endsyntax#} bits.9163 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).Int.bits){#endsyntax#} bits.
9164 This is because {#syntax#}shift_amt >= @typeInfo(T).Int.bits{#endsyntax#} is undefined behavior.9164 This is because {#syntax#}shift_amt >= @typeInfo(T).Int.bits{#endsyntax#} is undefined behavior.
9165 </p>9165 </p>
9166 <p>
9167 {#syntax#}comptime_int{#endsyntax#} is modeled as an integer with an infinite number of bits,
9168 meaning that in such case, {#syntax#}@shlExact{#endsyntax#} always produces a result and
9169 cannot produce a compile error.
9170 </p>
9166 {#see_also|@shrExact|@shlWithOverflow#}9171 {#see_also|@shrExact|@shlWithOverflow#}
9167 {#header_close#}9172 {#header_close#}
91689173
src/Sema.zig+5-17
...@@ -13247,32 +13247,20 @@ fn zirShl(...@@ -13247,32 +13247,20 @@ fn zirShl(
13247 }13247 }
13248 break :rs rhs_src;13248 break :rs rhs_src;
13249 };13249 };
1325013250 const val = if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
13251 const val = switch (air_tag) {13251 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod)
13252 else switch (air_tag) {
13252 .shl_exact => val: {13253 .shl_exact => val: {
13253 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod);13254 const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod);
13254 if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) {
13255 break :val shifted.wrapped_result;
13256 }
13257 if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) {13255 if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) {
13258 break :val shifted.wrapped_result;13256 break :val shifted.wrapped_result;
13259 }13257 }
13260 return sema.fail(block, src, "operation caused overflow", .{});13258 return sema.fail(block, src, "operation caused overflow", .{});
13261 },13259 },
1326213260 .shl_sat => try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod),
13263 .shl_sat => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)13261 .shl => try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod),
13264 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod)
13265 else
13266 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod),
13267
13268 .shl => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt)
13269 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod)
13270 else
13271 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod),
13272
13273 else => unreachable,13262 else => unreachable,
13274 };13263 };
13275
13276 return Air.internedToRef(val.toIntern());13264 return Air.internedToRef(val.toIntern());
13277 } else lhs_src;13265 } else lhs_src;
1327813266
test/behavior/math.zig+2
...@@ -1314,6 +1314,8 @@ test "exact shift left" {...@@ -1314,6 +1314,8 @@ test "exact shift left" {
13141314
1315 try testShlExact(0b00110101);1315 try testShlExact(0b00110101);
1316 try comptime testShlExact(0b00110101);1316 try comptime testShlExact(0b00110101);
1317
1318 if (@shlExact(1, 1) != 2) @compileError("should be 2");
1317}1319}
1318fn testShlExact(x: u8) !void {1320fn testShlExact(x: u8) !void {
1319 const shifted = @shlExact(x, 2);1321 const shifted = @shlExact(x, 2);