diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 5030c6233f6..f54ddd9f4d4 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -563,13 +563,36 @@ impl AcirContext { // lhs = rhs * q + r // // If predicate is zero, `q_witness` and `r_witness` will be 0 + let zero = self.add_constant(FieldElement::zero()); + if self.var_to_expression(predicate)?.is_zero() { + return Ok((zero, zero)); + } + + match (self.var_to_expression(lhs)?.to_const(), self.var_to_expression(rhs)?.to_const()) { + // If `lhs` and `rhs` are known constants then we can calculate the result at compile time. + // `rhs` must be non-zero. + (Some(lhs_const), Some(rhs_const)) if rhs_const != FieldElement::zero() => { + let quotient = lhs_const.to_u128() / rhs_const.to_u128(); + let remainder = lhs_const.to_u128() - quotient * rhs_const.to_u128(); + + let quotient_var = self.add_constant(FieldElement::from(quotient)); + let remainder_var = self.add_constant(FieldElement::from(remainder)); + return Ok((quotient_var, remainder_var)); + } + + // If `rhs` is one then the division is a noop. + (_, Some(rhs_const)) if rhs_const == FieldElement::one() => { + return Ok((lhs, zero)); + } + + _ => (), + } // Check that we the rhs is not zero. // Otherwise, when executing the brillig quotient we may attempt to divide by zero, causing a VM panic. // // When the predicate is 0, the equation always passes. // When the predicate is 1, the rhs must not be 0. - let zero = self.add_constant(FieldElement::zero()); let one = self.add_constant(FieldElement::one()); let rhs_expr = self.var_to_expression(rhs)?; diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz index c41feb2df21..7380f30d354 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz index b99f86a0339..2ff44d73044 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/conditional_1/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz index 0600c1dfc78..9a9f3a76992 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/simple_shield/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz index 70fa092b84d..30b5d36a2e3 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/acir.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz index a7846969bd8..1cbd7129bb0 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz and b/tooling/nargo_cli/tests/acir_artifacts/slice_dynamic_index/target/witness.gz differ diff --git a/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz index b2ec8995408..70a32bccf6f 100644 Binary files a/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz and b/tooling/nargo_cli/tests/acir_artifacts/slices/target/acir.gz differ