diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs index 16b7b3ea01b..1fdfb8dcf59 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs @@ -528,6 +528,19 @@ impl<'a> FunctionContext<'a> { /// ... This is the current insert point after codegen_for finishes ... /// ``` fn codegen_for(&mut self, for_expr: &ast::For) -> Result { + self.builder.set_location(for_expr.start_range_location); + let start_index = self.codegen_non_tuple_expression(&for_expr.start_range)?; + + self.builder.set_location(for_expr.end_range_location); + let end_index = self.codegen_non_tuple_expression(&for_expr.end_range)?; + + if let (Some(start_constant), Some(end_constant)) = (self.builder.current_function.dfg.get_numeric_constant(start_index), self.builder.current_function.dfg.get_numeric_constant(end_index)) { + // If we can determine that the loop contains zero iterations then we can short-circuit codegen. + if start_constant == end_constant { + return Ok(Self::unit_value()) + } + } + let loop_entry = self.builder.insert_block(); let loop_body = self.builder.insert_block(); let loop_end = self.builder.insert_block(); @@ -540,11 +553,6 @@ impl<'a> FunctionContext<'a> { // within the loop which need to jump to them. self.enter_loop(loop_entry, loop_index, loop_end); - self.builder.set_location(for_expr.start_range_location); - let start_index = self.codegen_non_tuple_expression(&for_expr.start_range)?; - - self.builder.set_location(for_expr.end_range_location); - let end_index = self.codegen_non_tuple_expression(&for_expr.end_range)?; // Set the location of the initial jmp instruction to the start range. This is the location // used to issue an error if the start range cannot be determined at compile-time.