Skip to content

Commit

Permalink
feat: convert constant right shifts into divisions
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench committed Feb 8, 2024
1 parent 3dbdca7 commit eff2d9f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
23 changes: 21 additions & 2 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,27 @@ impl Binary {
return SimplifyResult::SimplifiedTo(zero);
}
}
BinaryOp::Shl | BinaryOp::Shr => (),
}
BinaryOp::Shl => return SimplifyResult::None,
BinaryOp::Shr => {
// Bit shifts by constants can be treated as divisions.
if let Some(rhs_const) = rhs {
if rhs_const >= FieldElement::from(operand_type.bit_size() as u128) {
// Shifting by the full width of the operand type, any `lhs` goes to zero.
let zero = dfg.make_constant(FieldElement::zero(), operand_type);
return SimplifyResult::SimplifiedTo(zero);
}

// `two_pow_rhs` is limited to be at most `2 ^ {operand_bitsize - 1}` so it fits in `operand_type`.

Check warning on line 234 in compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (bitsize)
let two_pow_rhs = FieldElement::from(2u128).pow(&rhs_const);
let two_pow_rhs = dfg.make_constant(two_pow_rhs, operand_type);
return SimplifyResult::SimplifiedToInstruction(Instruction::binary(
BinaryOp::Div,
self.lhs,
two_pow_rhs,
));
}
}
};
SimplifyResult::None
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ impl Context<'_> {
rhs: ValueId,
bit_size: u32,
) -> ValueId {
let lhs_typ = self.function.dfg.type_of_value(lhs);
let base = self.field_constant(FieldElement::from(2_u128));
// we can safely cast to unsigned because overflow_checks prevent bit-shift with a negative value
let rhs_unsigned = self.insert_cast(rhs, Type::unsigned(bit_size));
Expand Down

0 comments on commit eff2d9f

Please sign in to comment.