From 0028e359f7503caffdf215cf55ca69376bfbba4b Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 2 Apr 2024 13:39:27 +0100 Subject: [PATCH 1/4] feat: improve SSA type-awareness in EQ and MUL instructions --- .../src/ssa/ir/instruction/binary.rs | 35 +++++++++++++++++++ 1 file changed, 35 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..80f3d4cc31c 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -130,6 +130,11 @@ 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 + { + return SimplifyResult::SimplifiedTo(self.lhs); + } } BinaryOp::Div => { if rhs_is_one { @@ -164,6 +169,36 @@ 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. + match (lhs, rhs) { + (Some(lhs), None) => { + let max_possible_value = + 2u128.pow(dfg.get_value_max_num_bits(self.rhs)) - 1; + if lhs > max_possible_value.into() { + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); + } + } + + (None, Some(rhs)) => { + let max_possible_value = + 2u128.pow(dfg.get_value_max_num_bits(self.lhs)) - 1; + if rhs > max_possible_value.into() { + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); + } + } + + (None, None) => (), + (Some(_), Some(_)) => { + unreachable!("Constant binary instructions should be handled above") + } + } + } + if operand_type == Type::bool() { // Simplify forms of `(boolean == true)` into `boolean` if lhs_is_one { From 0927c65284e47a9a5b40120abd799bca91e1913b Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 2 Apr 2024 14:01:34 +0100 Subject: [PATCH 2/4] Update compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs --- compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs index 80f3d4cc31c..5d5a5ab4f67 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -133,6 +133,7 @@ impl Binary { 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); } } From 37345f4a0c40ee280384480f1cbde7f98fc7daa4 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 2 Apr 2024 14:48:52 +0100 Subject: [PATCH 3/4] Update compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs Co-authored-by: jfecher --- .../src/ssa/ir/instruction/binary.rs | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs index 5d5a5ab4f67..ab23f21fa87 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -174,28 +174,15 @@ impl Binary { 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. - match (lhs, rhs) { - (Some(lhs), None) => { - let max_possible_value = - 2u128.pow(dfg.get_value_max_num_bits(self.rhs)) - 1; - if lhs > max_possible_value.into() { - let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); - return SimplifyResult::SimplifiedTo(zero); - } - } - - (None, Some(rhs)) => { - let max_possible_value = - 2u128.pow(dfg.get_value_max_num_bits(self.lhs)) - 1; - if rhs > max_possible_value.into() { - let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); - return SimplifyResult::SimplifiedTo(zero); - } - } - - (None, None) => (), - (Some(_), Some(_)) => { - unreachable!("Constant binary instructions should be handled above") + 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); } } } From 2e61d433116518f04add89cc224cafb05a2b9180 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:04:27 +0100 Subject: [PATCH 4/4] Update compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs --- compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs index ab23f21fa87..e491807995b 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -176,7 +176,6 @@ impl Binary { // 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;