Skip to content

Commit

Permalink
feat: remove truncations of the output of divisions which ensure trun…
Browse files Browse the repository at this point in the history
…cation is noop
  • Loading branch information
TomAFrench committed Jan 4, 2024
1 parent 75e0d8c commit c1eb716
Showing 1 changed file with 44 additions and 9 deletions.
53 changes: 44 additions & 9 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,16 +532,51 @@ impl Instruction {
let truncated = numeric_constant.to_u128() % integer_modulus;
SimplifiedTo(dfg.make_constant(truncated.into(), typ))
} else if let Value::Instruction { instruction, .. } = &dfg[dfg.resolve(*value)] {
if let Instruction::Truncate { bit_size: src_bit_size, .. } = &dfg[*instruction]
{
// If we're truncating the value to fit into the same or larger bit size then this is a noop.
if src_bit_size <= bit_size && src_bit_size <= max_bit_size {
SimplifiedTo(*value)
} else {
None
match &dfg[*instruction] {
Instruction::Truncate { bit_size: src_bit_size, .. } => {
// If we're truncating the value to fit into the same or larger bit size then this is a noop.
if src_bit_size <= bit_size && src_bit_size <= max_bit_size {
SimplifiedTo(*value)
} else {
None
}
}
} else {
None

Instruction::Binary(Binary {
lhs, rhs, operator: BinaryOp::Div, ..
}) if dfg.is_constant(*rhs) => {
// If we're truncating the result of a division by a constant denominator, we can
// reason about the maximum bit size of the result and whether a truncation is necessary.
fn get_type_size(typ: &Type) -> u32 {
match typ {
Type::Numeric(NumericType::NativeField) => {
FieldElement::max_num_bits()
}
Type::Numeric(
NumericType::Unsigned { bit_size }
| NumericType::Signed { bit_size },
) => *bit_size,
_ => unreachable!("Should only be called with primitive types"),
}
}

let numerator_type = dfg.type_of_value(*lhs);
let divisor = dfg
.get_numeric_constant(*rhs)
.expect("rhs is checked to be constant.");

let divisor_bits = divisor.num_bits();
let max_numerator_bits = get_type_size(&numerator_type);

let max_quotient_bits = max_numerator_bits - divisor_bits + 1;
if max_quotient_bits <= *bit_size {
SimplifiedTo(*value)
} else {
None
}
}

_ => None,
}
} else {
None
Expand Down

0 comments on commit c1eb716

Please sign in to comment.