authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-06 05:05:43+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-06 05:05:43+02:00
log069986fdbf4c6fe99547a9cf9df3b44d4c030c43
treef357009217b6908f4af6f7831c9645fc5d7bf2fa
parenta7a6d1730db30d6541eedf3be1531d323eb7a93a
parent8d47bbdbe032cb49aac829ba349669a63cc17943

Merge pull request 'Sema: emit shr instead of shr_exact when @shrExact is used and wantSafety is true' (#37104) from rpkak/zig:safe-shrExact into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37104 Reviewed-by: Alex Rønne Petersen <alex@alexrp.com>

2 files changed, 18 insertions(+), 24 deletions(-)

doc/langref/runtime_shrExact_overflow.zig-3
......@@ -1,4 +1,3 @@
1const builtin = @import("builtin");
21const std = @import("std");
32
43pub fn main() void {
......@@ -6,8 +5,6 @@ pub fn main() void {
65 _ = &x;
76 const y = @shrExact(x, 2);
87 std.debug.print("value: {}\n", .{y});
9
10 if ((builtin.cpu.arch.isPowerPC() or builtin.cpu.arch.isRISCV() or builtin.cpu.arch.isLoongArch() or builtin.cpu.arch == .s390x) and builtin.zig_backend == .stage2_llvm) @panic("https://github.com/ziglang/zig/issues/24304");
118}
129
1310// exe=fail
src/Sema.zig+18-21
......@@ -1231,8 +1231,8 @@ fn analyzeBodyInner(
12311231 .ref => try sema.zirRef(block, inst),
12321232 .deref => try sema.zirDeref(block, inst),
12331233 .ref_deref => try sema.zirRefDeref(block, inst),
1234 .shr => try sema.zirShr(block, inst, .shr),
1235 .shr_exact => try sema.zirShr(block, inst, .shr_exact),
1234 .shr => try sema.zirShr(block, inst, false),
1235 .shr_exact => try sema.zirShr(block, inst, true),
12361236 .slice_end => try sema.zirSliceEnd(block, inst),
12371237 .slice_sentinel => try sema.zirSliceSentinel(block, inst),
12381238 .slice_start => try sema.zirSliceStart(block, inst),
......@@ -13176,7 +13176,7 @@ fn zirShr(
1317613176 sema: *Sema,
1317713177 block: *Block,
1317813178 inst: Zir.Inst.Index,
13179 air_tag: Air.Inst.Tag,
13179 exact: bool,
1318013180) CompileError!Air.Inst.Ref {
1318113181 const pt = sema.pt;
1318213182 const zcu = pt.zcu;
......@@ -13188,16 +13188,15 @@ fn zirShr(
1318813188 const rhs_ty = sema.typeOf(rhs);
1318913189
1319013190 const src = block.nodeOffset(inst_data.src_node);
13191 const lhs_src = switch (air_tag) {
13192 .shr => block.src(.{ .node_offset_bin_lhs = inst_data.src_node }),
13193 .shr_exact => block.builtinCallArgSrc(inst_data.src_node, 0),
13194 else => unreachable,
13195 };
13196 const rhs_src = switch (air_tag) {
13197 .shr => block.src(.{ .node_offset_bin_rhs = inst_data.src_node }),
13198 .shr_exact => block.builtinCallArgSrc(inst_data.src_node, 1),
13199 else => unreachable,
13200 };
13191 const lhs_src = if (exact)
13192 block.builtinCallArgSrc(inst_data.src_node, 0)
13193 else
13194 block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
13195
13196 const rhs_src = if (exact)
13197 block.builtinCallArgSrc(inst_data.src_node, 1)
13198 else
13199 block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
1320113200
1320213201 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1320313202 const scalar_ty = lhs_ty.scalarType(zcu);
......@@ -13208,11 +13207,7 @@ fn zirShr(
1320813207 const runtime_src = rs: {
1320913208 if (maybe_rhs_val) |rhs_val| {
1321013209 if (maybe_lhs_val) |lhs_val| {
13211 return .fromValue(try arith.shr(sema, block, lhs_ty, rhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {
13212 .shr => .shr,
13213 .shr_exact => .shr_exact,
13214 else => unreachable,
13215 }));
13210 return .fromValue(try arith.shr(sema, block, lhs_ty, rhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, if (exact) .shr_exact else .shr));
1321613211 }
1321713212 if (rhs_val.isUndef(zcu)) {
1321813213 return sema.failWithUseOfUndef(block, rhs_src, null);
......@@ -13269,8 +13264,10 @@ fn zirShr(
1326913264 break :rs rhs_src;
1327013265 };
1327113266 try sema.requireRuntimeBlock(block, src, runtime_src);
13272 const result = try block.addBinOp(air_tag, lhs, rhs);
13273 if (block.wantSafety()) {
13267
13268 const safety = block.wantSafety();
13269 const result = try block.addBinOp(if (!exact or safety) .shr else .shr_exact, lhs, rhs);
13270 if (safety) {
1327413271 const bit_count = scalar_ty.intInfo(zcu).bits;
1327513272 if (!std.math.isPowerOfTwo(bit_count)) {
1327613273 const bit_count_val = try pt.intValue(rhs_ty.scalarType(zcu), bit_count);
......@@ -13286,7 +13283,7 @@ fn zirShr(
1328613283 try sema.addSafetyCheck(block, src, ok, .shift_rhs_too_big);
1328713284 }
1328813285
13289 if (air_tag == .shr_exact) {
13286 if (exact) {
1329013287 const back = try block.addBinOp(.shl, result, rhs);
1329113288
1329213289 const ok = if (rhs_ty.zigTypeTag(zcu) == .vector) ok: {