authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-18 16:28:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-18 19:20:19-07:00
log12a7a0d76f9435c8c538f762daa79a49ca0470af
tree8286a636fb95665ad30be61653bf74031a3be213
parent8b05205bb71fca55569a9ff4cab89ec9e09640ba

omit safety check when incrementing for loop counter

Since for loops are statically analyzed to have an upper bound, and the loop counter is a usize, it is impossible for it to overflow.

4 files changed, 21 insertions(+), 12 deletions(-)

src/AstGen.zig+2-1
......@@ -2400,6 +2400,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
24002400 .add,
24012401 .addwrap,
24022402 .add_sat,
2403 .add_unsafe,
24032404 .param,
24042405 .param_comptime,
24052406 .param_anytype,
......@@ -6440,7 +6441,7 @@ fn forExpr(
64406441 try loop_scope.instructions.append(gpa, cond_block);
64416442
64426443 // Increment the index variable.
6443 const index_plus_one = try loop_scope.addPlNode(.add, node, Zir.Inst.Bin{
6444 const index_plus_one = try loop_scope.addPlNode(.add_unsafe, node, Zir.Inst.Bin{
64446445 .lhs = index,
64456446 .rhs = .one_usize,
64466447 });
src/Sema.zig+13-11
......@@ -1060,15 +1060,16 @@ fn analyzeBodyInner(
10601060 .error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
10611061 .error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),
10621062
1063 .add => try sema.zirArithmetic(block, inst, .add),
1064 .addwrap => try sema.zirArithmetic(block, inst, .addwrap),
1065 .add_sat => try sema.zirArithmetic(block, inst, .add_sat),
1066 .mul => try sema.zirArithmetic(block, inst, .mul),
1067 .mulwrap => try sema.zirArithmetic(block, inst, .mulwrap),
1068 .mul_sat => try sema.zirArithmetic(block, inst, .mul_sat),
1069 .sub => try sema.zirArithmetic(block, inst, .sub),
1070 .subwrap => try sema.zirArithmetic(block, inst, .subwrap),
1071 .sub_sat => try sema.zirArithmetic(block, inst, .sub_sat),
1063 .add => try sema.zirArithmetic(block, inst, .add, true),
1064 .addwrap => try sema.zirArithmetic(block, inst, .addwrap, true),
1065 .add_sat => try sema.zirArithmetic(block, inst, .add_sat, true),
1066 .add_unsafe=> try sema.zirArithmetic(block, inst, .add_unsafe, false),
1067 .mul => try sema.zirArithmetic(block, inst, .mul, true),
1068 .mulwrap => try sema.zirArithmetic(block, inst, .mulwrap, true),
1069 .mul_sat => try sema.zirArithmetic(block, inst, .mul_sat, true),
1070 .sub => try sema.zirArithmetic(block, inst, .sub, true),
1071 .subwrap => try sema.zirArithmetic(block, inst, .subwrap, true),
1072 .sub_sat => try sema.zirArithmetic(block, inst, .sub_sat, true),
10721073
10731074 .div => try sema.zirDiv(block, inst),
10741075 .div_exact => try sema.zirDivExact(block, inst),
......@@ -12887,6 +12888,7 @@ fn zirArithmetic(
1288712888 block: *Block,
1288812889 inst: Zir.Inst.Index,
1288912890 zir_tag: Zir.Inst.Tag,
12891 safety: bool,
1289012892) CompileError!Air.Inst.Ref {
1289112893 const tracy = trace(@src());
1289212894 defer tracy.end();
......@@ -12899,7 +12901,7 @@ fn zirArithmetic(
1289912901 const lhs = try sema.resolveInst(extra.lhs);
1290012902 const rhs = try sema.resolveInst(extra.rhs);
1290112903
12902 return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, true);
12904 return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, safety);
1290312905}
1290412906
1290512907fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -14250,7 +14252,7 @@ fn analyzeArithmetic(
1425014252 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
1425114253 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
1425214254 switch (zir_tag) {
14253 .add => {
14255 .add, .add_unsafe => {
1425414256 // For integers:intAddSat
1425514257 // If either of the operands are zero, then the other operand is
1425614258 // returned, even if it is undefined.
src/Zir.zig+5
......@@ -137,6 +137,8 @@ pub const Inst = struct {
137137 /// Saturating addition.
138138 /// Uses the `pl_node` union field. Payload is `Bin`.
139139 add_sat,
140 /// The same as `add` except no safety check.
141 add_unsafe,
140142 /// Arithmetic subtraction. Asserts no integer overflow.
141143 /// Uses the `pl_node` union field. Payload is `Bin`.
142144 sub,
......@@ -1023,6 +1025,7 @@ pub const Inst = struct {
10231025 .add,
10241026 .addwrap,
10251027 .add_sat,
1028 .add_unsafe,
10261029 .alloc,
10271030 .alloc_mut,
10281031 .alloc_comptime_mut,
......@@ -1338,6 +1341,7 @@ pub const Inst = struct {
13381341 .add,
13391342 .addwrap,
13401343 .add_sat,
1344 .add_unsafe,
13411345 .alloc,
13421346 .alloc_mut,
13431347 .alloc_comptime_mut,
......@@ -1570,6 +1574,7 @@ pub const Inst = struct {
15701574 .add = .pl_node,
15711575 .addwrap = .pl_node,
15721576 .add_sat = .pl_node,
1577 .add_unsafe = .pl_node,
15731578 .sub = .pl_node,
15741579 .subwrap = .pl_node,
15751580 .sub_sat = .pl_node,
src/print_zir.zig+1
......@@ -296,6 +296,7 @@ const Writer = struct {
296296 .add,
297297 .addwrap,
298298 .add_sat,
299 .add_unsafe,
299300 .array_cat,
300301 .array_mul,
301302 .mul,