From bae2e532bc5975393935b6149b0c63fac3ffac06 Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 8 Aug 2023 11:40:11 +0100 Subject: [PATCH 1/2] feat: Optimize `x < 0` for unsigned `x` to false --- crates/noirc_evaluator/src/ssa/ir/instruction.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/crates/noirc_evaluator/src/ssa/ir/instruction.rs index 433bf2013a7..204258145ce 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction.rs @@ -593,6 +593,13 @@ impl Binary { let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); return SimplifyResult::SimplifiedTo(zero); } + if let Type::Numeric(NumericType::Unsigned { .. }) = operand_type { + if rhs_is_zero { + // Unsigned values cannot be less than zero. + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); + } + } } BinaryOp::And => { if lhs_is_zero || rhs_is_zero { From e667b8f50cd31a47e1abafb40df26349557acf48 Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 8 Aug 2023 18:43:25 +0100 Subject: [PATCH 2/2] chore: add `Type::is_unsigned(&self)` method --- crates/noirc_evaluator/src/ssa/ir/instruction.rs | 10 ++++------ crates/noirc_evaluator/src/ssa/ir/types.rs | 5 +++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/crates/noirc_evaluator/src/ssa/ir/instruction.rs index 204258145ce..30d9027180f 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction.rs @@ -593,12 +593,10 @@ impl Binary { let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); return SimplifyResult::SimplifiedTo(zero); } - if let Type::Numeric(NumericType::Unsigned { .. }) = operand_type { - if rhs_is_zero { - // Unsigned values cannot be less than zero. - let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); - return SimplifyResult::SimplifiedTo(zero); - } + if operand_type.is_unsigned() && rhs_is_zero { + // Unsigned values cannot be less than zero. + let zero = dfg.make_constant(FieldElement::zero(), Type::bool()); + return SimplifyResult::SimplifiedTo(zero); } } BinaryOp::And => { diff --git a/crates/noirc_evaluator/src/ssa/ir/types.rs b/crates/noirc_evaluator/src/ssa/ir/types.rs index 38dd6125121..e8110f0901b 100644 --- a/crates/noirc_evaluator/src/ssa/ir/types.rs +++ b/crates/noirc_evaluator/src/ssa/ir/types.rs @@ -37,6 +37,11 @@ pub(crate) enum Type { } impl Type { + /// Returns whether the `Type` represents an unsigned numeric type. + pub(crate) fn is_unsigned(&self) -> bool { + matches!(self, Type::Numeric(NumericType::Unsigned { .. })) + } + /// Create a new signed integer type with the given amount of bits. pub(crate) fn signed(bit_size: u32) -> Type { Type::Numeric(NumericType::Signed { bit_size })