From 70f2435685d1d2a8fdd28160187d4312ec78d294 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 12 Feb 2024 18:30:48 +0000 Subject: [PATCH] feat: replace modulo operations with truncations where possible (#4329) # Description ## Problem\* Resolves ## Summary\* In the vein of #4327. We now replace modulo operations with a power of two with the more specific `Instruction::Truncate`. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** 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. --- .../src/ssa/ir/instruction/binary.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs index e94ac60ac00..36f3ae8620b 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs @@ -141,6 +141,23 @@ impl Binary { let zero = dfg.make_constant(FieldElement::zero(), operand_type); return SimplifyResult::SimplifiedTo(zero); } + if operand_type.is_unsigned() { + // lhs % 2**bit_size is equivalent to truncating `lhs` to `bit_size` bits. + // We then convert to a truncation for consistency, allowing more optimizations. + if let Some(modulus) = rhs { + let modulus = modulus.to_u128(); + if modulus.is_power_of_two() { + let bit_size = modulus.ilog2(); + return SimplifyResult::SimplifiedToInstruction( + Instruction::Truncate { + value: self.lhs, + bit_size, + max_bit_size: operand_type.bit_size(), + }, + ); + } + } + } } BinaryOp::Eq => { if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) {