From d2966786435242411e8986ddcf3cf0cff262926a Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Fri, 28 Jul 2023 03:25:57 +0000 Subject: [PATCH] feat: Remove an unnecessary witness in `mul_with_witness` --- .../acir_gen/acir_ir/generated_acir.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs index 18c7216a6fa..5e6248507d8 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs @@ -257,7 +257,7 @@ impl GeneratedAcir { /// If one has multiplicative term and the other is of degree one or more, /// the function creates [intermediate variables][`Witness`] accordingly. /// There are two cases where we can optimize the multiplication between two expressions: - /// 1. If both expressions have at most a total degree of 1 in each term, then we can just multiply them + /// 1. If the sum of the degrees of both expressions is at most 2, then we can just multiply them /// as each term in the result will be degree-2. /// 2. If one expression is a constant, then we can just multiply the constant with the other expression /// @@ -268,10 +268,14 @@ impl GeneratedAcir { let lhs_is_linear = lhs.is_linear(); let rhs_is_linear = rhs.is_linear(); - // Case 1: Both expressions have at most a total degree of 1 in each term - if lhs_is_linear && rhs_is_linear { - return (lhs * rhs) - .expect("one of the expressions is a constant and so this should not fail"); + // Case 1: The sum of the degrees of both expressions is at most 2. + // + // If one of the expressions is constant then it does not increase the degree when multiplying by another expression. + // If both of the expressions are linear (degree <=1) then the product will be at most degree 2. + let both_are_linear = lhs_is_linear && rhs_is_linear; + let either_is_const = lhs.is_const() || rhs.is_const(); + if both_are_linear || either_is_const { + return (lhs * rhs).expect("Both expressions are degree <= 1"); } // Case 2: One or both of the sides needs to be reduced to a degree-1 univariate polynomial @@ -285,7 +289,7 @@ impl GeneratedAcir { // rhs, we only need to square the lhs. if lhs == rhs { return (&*lhs_reduced * &*lhs_reduced) - .expect("Both expressions are reduced to be degree<=1"); + .expect("Both expressions are reduced to be degree <= 1"); }; let rhs_reduced = if rhs_is_linear { @@ -294,7 +298,7 @@ impl GeneratedAcir { Cow::Owned(self.get_or_create_witness(rhs).into()) }; - (&*lhs_reduced * &*rhs_reduced).expect("Both expressions are reduced to be degree<=1") + (&*lhs_reduced * &*rhs_reduced).expect("Both expressions are reduced to be degree <= 1") } /// Signed division lhs / rhs