diff --git a/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs b/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs index caf65c85a7e..6d74e49b03b 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs @@ -158,7 +158,8 @@ impl DataFlowGraph { SimplifiedToMultiple(simplification) } SimplifyResult::Remove => InstructionRemoved, - SimplifyResult::None => { + result @ (SimplifyResult::SimplifiedToInstruction(_) | SimplifyResult::None) => { + let instruction = result.instruction().unwrap_or(instruction); let id = self.make_instruction(instruction, ctrl_typevars); self.blocks[block].insert_instruction(id); if let Some(location) = location { diff --git a/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs b/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs index a56b12ab875..afb47d423e2 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs @@ -736,6 +736,11 @@ impl Binary { if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { return SimplifyResult::SimplifiedTo(self.lhs); } + if operand_type == Type::bool() { + // Boolean AND is equivalent to multiplication, which is a cheaper operation. + let instruction = Instruction::binary(BinaryOp::Mul, self.lhs, self.rhs); + return SimplifyResult::SimplifiedToInstruction(instruction); + } } BinaryOp::Or => { if lhs_is_zero { @@ -898,9 +903,21 @@ pub(crate) enum SimplifyResult { /// a function such as a tuple SimplifiedToMultiple(Vec), + /// Replace this function with an simpler but equivalent function. + SimplifiedToInstruction(Instruction), + /// Remove the instruction, it is unnecessary Remove, /// Instruction could not be simplified None, } + +impl SimplifyResult { + pub(crate) fn instruction(self) -> Option { + match self { + SimplifyResult::SimplifiedToInstruction(instruction) => Some(instruction), + _ => None, + } + } +}