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.
This commit is contained in:
Andrew Kelley 2023-02-18 16:28:21 -07:00
parent 8b05205bb7
commit 12a7a0d76f
4 changed files with 21 additions and 12 deletions

View file

@ -2400,6 +2400,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
.add,
.addwrap,
.add_sat,
.add_unsafe,
.param,
.param_comptime,
.param_anytype,
@ -6440,7 +6441,7 @@ fn forExpr(
try loop_scope.instructions.append(gpa, cond_block);
// Increment the index variable.
const index_plus_one = try loop_scope.addPlNode(.add, node, Zir.Inst.Bin{
const index_plus_one = try loop_scope.addPlNode(.add_unsafe, node, Zir.Inst.Bin{
.lhs = index,
.rhs = .one_usize,
});

View file

@ -1060,15 +1060,16 @@ fn analyzeBodyInner(
.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),
.add => try sema.zirArithmetic(block, inst, .add),
.addwrap => try sema.zirArithmetic(block, inst, .addwrap),
.add_sat => try sema.zirArithmetic(block, inst, .add_sat),
.mul => try sema.zirArithmetic(block, inst, .mul),
.mulwrap => try sema.zirArithmetic(block, inst, .mulwrap),
.mul_sat => try sema.zirArithmetic(block, inst, .mul_sat),
.sub => try sema.zirArithmetic(block, inst, .sub),
.subwrap => try sema.zirArithmetic(block, inst, .subwrap),
.sub_sat => try sema.zirArithmetic(block, inst, .sub_sat),
.add => try sema.zirArithmetic(block, inst, .add, true),
.addwrap => try sema.zirArithmetic(block, inst, .addwrap, true),
.add_sat => try sema.zirArithmetic(block, inst, .add_sat, true),
.add_unsafe=> try sema.zirArithmetic(block, inst, .add_unsafe, false),
.mul => try sema.zirArithmetic(block, inst, .mul, true),
.mulwrap => try sema.zirArithmetic(block, inst, .mulwrap, true),
.mul_sat => try sema.zirArithmetic(block, inst, .mul_sat, true),
.sub => try sema.zirArithmetic(block, inst, .sub, true),
.subwrap => try sema.zirArithmetic(block, inst, .subwrap, true),
.sub_sat => try sema.zirArithmetic(block, inst, .sub_sat, true),
.div => try sema.zirDiv(block, inst),
.div_exact => try sema.zirDivExact(block, inst),
@ -12887,6 +12888,7 @@ fn zirArithmetic(
block: *Block,
inst: Zir.Inst.Index,
zir_tag: Zir.Inst.Tag,
safety: bool,
) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
@ -12899,7 +12901,7 @@ fn zirArithmetic(
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, true);
return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, sema.src, lhs_src, rhs_src, safety);
}
fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@ -14250,7 +14252,7 @@ fn analyzeArithmetic(
const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs);
const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
switch (zir_tag) {
.add => {
.add, .add_unsafe => {
// For integers:intAddSat
// If either of the operands are zero, then the other operand is
// returned, even if it is undefined.

View file

@ -137,6 +137,8 @@ pub const Inst = struct {
/// Saturating addition.
/// Uses the `pl_node` union field. Payload is `Bin`.
add_sat,
/// The same as `add` except no safety check.
add_unsafe,
/// Arithmetic subtraction. Asserts no integer overflow.
/// Uses the `pl_node` union field. Payload is `Bin`.
sub,
@ -1023,6 +1025,7 @@ pub const Inst = struct {
.add,
.addwrap,
.add_sat,
.add_unsafe,
.alloc,
.alloc_mut,
.alloc_comptime_mut,
@ -1338,6 +1341,7 @@ pub const Inst = struct {
.add,
.addwrap,
.add_sat,
.add_unsafe,
.alloc,
.alloc_mut,
.alloc_comptime_mut,
@ -1570,6 +1574,7 @@ pub const Inst = struct {
.add = .pl_node,
.addwrap = .pl_node,
.add_sat = .pl_node,
.add_unsafe = .pl_node,
.sub = .pl_node,
.subwrap = .pl_node,
.sub_sat = .pl_node,

View file

@ -296,6 +296,7 @@ const Writer = struct {
.add,
.addwrap,
.add_sat,
.add_unsafe,
.array_cat,
.array_mul,
.mul,