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...@@ -2400,6 +2400,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2400 .add,2400 .add,
2401 .addwrap,2401 .addwrap,
2402 .add_sat,2402 .add_sat,
2403 .add_unsafe,
2403 .param,2404 .param,
2404 .param_comptime,2405 .param_comptime,
2405 .param_anytype,2406 .param_anytype,
...@@ -6440,7 +6441,7 @@ fn forExpr(...@@ -6440,7 +6441,7 @@ fn forExpr(
6440 try loop_scope.instructions.append(gpa, cond_block);6441 try loop_scope.instructions.append(gpa, cond_block);
64416442
6442 // Increment the index variable.6443 // 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{
6444 .lhs = index,6445 .lhs = index,
6445 .rhs = .one_usize,6446 .rhs = .one_usize,
6446 });6447 });
src/Sema.zig+13-11
...@@ -1060,15 +1060,16 @@ fn analyzeBodyInner(...@@ -1060,15 +1060,16 @@ fn analyzeBodyInner(
1060 .error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),1060 .error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
1061 .error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),1061 .error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),
10621062
1063 .add => try sema.zirArithmetic(block, inst, .add),1063 .add => try sema.zirArithmetic(block, inst, .add, true),
1064 .addwrap => try sema.zirArithmetic(block, inst, .addwrap),1064 .addwrap => try sema.zirArithmetic(block, inst, .addwrap, true),
1065 .add_sat => try sema.zirArithmetic(block, inst, .add_sat),1065 .add_sat => try sema.zirArithmetic(block, inst, .add_sat, true),
1066 .mul => try sema.zirArithmetic(block, inst, .mul),1066 .add_unsafe=> try sema.zirArithmetic(block, inst, .add_unsafe, false),
1067 .mulwrap => try sema.zirArithmetic(block, inst, .mulwrap),1067 .mul => try sema.zirArithmetic(block, inst, .mul, true),
1068 .mul_sat => try sema.zirArithmetic(block, inst, .mul_sat),1068 .mulwrap => try sema.zirArithmetic(block, inst, .mulwrap, true),
1069 .sub => try sema.zirArithmetic(block, inst, .sub),1069 .mul_sat => try sema.zirArithmetic(block, inst, .mul_sat, true),
1070 .subwrap => try sema.zirArithmetic(block, inst, .subwrap),1070 .sub => try sema.zirArithmetic(block, inst, .sub, true),
1071 .sub_sat => try sema.zirArithmetic(block, inst, .sub_sat),1071 .subwrap => try sema.zirArithmetic(block, inst, .subwrap, true),
1072 .sub_sat => try sema.zirArithmetic(block, inst, .sub_sat, true),
10721073
1073 .div => try sema.zirDiv(block, inst),1074 .div => try sema.zirDiv(block, inst),
1074 .div_exact => try sema.zirDivExact(block, inst),1075 .div_exact => try sema.zirDivExact(block, inst),
...@@ -12887,6 +12888,7 @@ fn zirArithmetic(...@@ -12887,6 +12888,7 @@ fn zirArithmetic(
12887 block: *Block,12888 block: *Block,
12888 inst: Zir.Inst.Index,12889 inst: Zir.Inst.Index,
12889 zir_tag: Zir.Inst.Tag,12890 zir_tag: Zir.Inst.Tag,
12891 safety: bool,
12890) CompileError!Air.Inst.Ref {12892) CompileError!Air.Inst.Ref {
12891 const tracy = trace(@src());12893 const tracy = trace(@src());
12892 defer tracy.end();12894 defer tracy.end();
...@@ -12899,7 +12901,7 @@ fn zirArithmetic(...@@ -12899,7 +12901,7 @@ fn zirArithmetic(
12899 const lhs = try sema.resolveInst(extra.lhs);12901 const lhs = try sema.resolveInst(extra.lhs);
12900 const rhs = try sema.resolveInst(extra.rhs);12902 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);
12903}12905}
1290412906
12905fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {12907fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -14250,7 +14252,7 @@ fn analyzeArithmetic(...@@ -14250,7 +14252,7 @@ fn analyzeArithmetic(
14250 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);14252 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
14251 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {14253 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
14252 switch (zir_tag) {14254 switch (zir_tag) {
14253 .add => {14255 .add, .add_unsafe => {
14254 // For integers:intAddSat14256 // For integers:intAddSat
14255 // If either of the operands are zero, then the other operand is14257 // If either of the operands are zero, then the other operand is
14256 // returned, even if it is undefined.14258 // returned, even if it is undefined.
src/Zir.zig+5
...@@ -137,6 +137,8 @@ pub const Inst = struct {...@@ -137,6 +137,8 @@ pub const Inst = struct {
137 /// Saturating addition.137 /// Saturating addition.
138 /// Uses the `pl_node` union field. Payload is `Bin`.138 /// Uses the `pl_node` union field. Payload is `Bin`.
139 add_sat,139 add_sat,
140 /// The same as `add` except no safety check.
141 add_unsafe,
140 /// Arithmetic subtraction. Asserts no integer overflow.142 /// Arithmetic subtraction. Asserts no integer overflow.
141 /// Uses the `pl_node` union field. Payload is `Bin`.143 /// Uses the `pl_node` union field. Payload is `Bin`.
142 sub,144 sub,
...@@ -1023,6 +1025,7 @@ pub const Inst = struct {...@@ -1023,6 +1025,7 @@ pub const Inst = struct {
1023 .add,1025 .add,
1024 .addwrap,1026 .addwrap,
1025 .add_sat,1027 .add_sat,
1028 .add_unsafe,
1026 .alloc,1029 .alloc,
1027 .alloc_mut,1030 .alloc_mut,
1028 .alloc_comptime_mut,1031 .alloc_comptime_mut,
...@@ -1338,6 +1341,7 @@ pub const Inst = struct {...@@ -1338,6 +1341,7 @@ pub const Inst = struct {
1338 .add,1341 .add,
1339 .addwrap,1342 .addwrap,
1340 .add_sat,1343 .add_sat,
1344 .add_unsafe,
1341 .alloc,1345 .alloc,
1342 .alloc_mut,1346 .alloc_mut,
1343 .alloc_comptime_mut,1347 .alloc_comptime_mut,
...@@ -1570,6 +1574,7 @@ pub const Inst = struct {...@@ -1570,6 +1574,7 @@ pub const Inst = struct {
1570 .add = .pl_node,1574 .add = .pl_node,
1571 .addwrap = .pl_node,1575 .addwrap = .pl_node,
1572 .add_sat = .pl_node,1576 .add_sat = .pl_node,
1577 .add_unsafe = .pl_node,
1573 .sub = .pl_node,1578 .sub = .pl_node,
1574 .subwrap = .pl_node,1579 .subwrap = .pl_node,
1575 .sub_sat = .pl_node,1580 .sub_sat = .pl_node,
src/print_zir.zig+1
...@@ -296,6 +296,7 @@ const Writer = struct {...@@ -296,6 +296,7 @@ const Writer = struct {
296 .add,296 .add,
297 .addwrap,297 .addwrap,
298 .add_sat,298 .add_sat,
299 .add_unsafe,
299 .array_cat,300 .array_cat,
300 .array_mul,301 .array_mul,
301 .mul,302 .mul,