From 8adee4ff9d09f89254afbedb57c89ac979f9199b Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:20:34 +0100 Subject: [PATCH] feat: improve SSA type-awareness in EQ and MUL instructions (#4691) # Description ## Problem\* Resolves ## Summary\* This PR adds some improvements for SSA generation for programs such as in #4688 where we now make more use of information on casted values. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher --- .../src/ssa/ir/instruction/binary.rs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs index 36f3ae8620b..e491807995b 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -130,6 +130,12 @@ impl Binary { let zero = dfg.make_constant(FieldElement::zero(), operand_type); return SimplifyResult::SimplifiedTo(zero); } + if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) + && dfg.get_value_max_num_bits(self.lhs) == 1 + { + // Squaring a boolean value is a noop. + return SimplifyResult::SimplifiedTo(self.lhs); + } } BinaryOp::Div => { if rhs_is_one { @@ -164,6 +170,22 @@ impl Binary { let one = dfg.make_constant(FieldElement::one(), Type::bool()); return SimplifyResult::SimplifiedTo(one); } + + if operand_type.is_unsigned() { + // If we're comparing a variable against a constant value which lies outside of the range of + // values which the variable's type can take, we can assume that the equality will be false. + let constant = lhs.or(rhs); + let non_constant = if lhs.is_some() { self.rhs } else { self.lhs }; + if let Some(constant) = constant { + let max_possible_value = + 2u128.pow(dfg.get_value_max_num_bits(non_constant)) - 1; + if constant > max_possible_value.into() { + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); + } + } + } + if operand_type == Type::bool() { // Simplify forms of `(boolean == true)` into `boolean` if lhs_is_one {