Skip to content

Commit

Permalink
feat: remove max_bit_size from Instruction::truncate
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench committed Jan 14, 2025
1 parent aa7b91c commit 59c33e5
Show file tree
Hide file tree
Showing 11 changed files with 25 additions and 37 deletions.
3 changes: 1 addition & 2 deletions compiler/noirc_evaluator/src/acir/acir_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1141,14 +1141,13 @@ impl<F: AcirField, B: BlackBoxFunctionSolver<F>> AcirContext<F, B> {
&mut self,
lhs: AcirVar,
rhs: u32,
max_bit_size: u32,
) -> Result<AcirVar, RuntimeError> {
// 2^{rhs}
let divisor = self.add_constant(F::from(2_u128).pow(&F::from(rhs as u128)));
let one = self.add_constant(F::one());

// Computes lhs = 2^{rhs} * q + r
let (_, remainder) = self.euclidean_division_var(lhs, divisor, max_bit_size, one)?;
let (_, remainder) = self.euclidean_division_var(lhs, divisor, F::max_num_bits(), one)?;

Ok(remainder)
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/noirc_evaluator/src/acir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,9 +745,9 @@ impl<'a> Context<'a> {
let result_acir_var = self.acir_context.not_var(acir_var, typ)?;
self.define_result_var(dfg, instruction_id, result_acir_var);
}
Instruction::Truncate { value, bit_size, max_bit_size } => {
Instruction::Truncate { value, bit_size } => {
let result_acir_var =
self.convert_ssa_truncate(*value, *bit_size, *max_bit_size, dfg)?;
self.convert_ssa_truncate(*value, *bit_size, dfg)?;
self.define_result_var(dfg, instruction_id, result_acir_var);
}
Instruction::EnableSideEffectsIf { condition } => {
Expand Down Expand Up @@ -2065,7 +2065,6 @@ impl<'a> Context<'a> {
&mut self,
value_id: ValueId,
bit_size: u32,
max_bit_size: u32,
dfg: &DataFlowGraph,
) -> Result<AcirVar, RuntimeError> {
let mut var = self.convert_numeric_value(value_id, dfg)?;
Expand All @@ -2090,7 +2089,7 @@ impl<'a> Context<'a> {
),
};

self.acir_context.truncate_var(var, bit_size, max_bit_size)
self.acir_context.truncate_var(var, bit_size)
}

/// Returns a vector of `AcirVar`s constrained to be result of the function call.
Expand Down
3 changes: 1 addition & 2 deletions compiler/noirc_evaluator/src/ssa/function_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,8 @@ impl FunctionBuilder {
&mut self,
value: ValueId,
bit_size: u32,
max_bit_size: u32,
) -> ValueId {
self.insert_instruction(Instruction::Truncate { value, bit_size, max_bit_size }, None)
self.insert_instruction(Instruction::Truncate { value, bit_size }, None)
.first()
}

Expand Down
13 changes: 6 additions & 7 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ pub(crate) enum Instruction {
Not(ValueId),

/// Truncates `value` to `bit_size`
Truncate { value: ValueId, bit_size: u32, max_bit_size: u32 },
Truncate { value: ValueId, bit_size: u32 },

/// Constrains two values to be equal to one another.
Constrain(ValueId, ValueId, Option<ConstrainError>),
Expand Down Expand Up @@ -635,10 +635,9 @@ impl Instruction {
}),
Instruction::Cast(value, typ) => Instruction::Cast(f(*value), *typ),
Instruction::Not(value) => Instruction::Not(f(*value)),
Instruction::Truncate { value, bit_size, max_bit_size } => Instruction::Truncate {
Instruction::Truncate { value, bit_size } => Instruction::Truncate {
value: f(*value),
bit_size: *bit_size,
max_bit_size: *max_bit_size,
},
Instruction::Constrain(lhs, rhs, assert_message) => {
// Must map the `lhs` and `rhs` first as the value `f` is moved with the closure
Expand Down Expand Up @@ -711,7 +710,7 @@ impl Instruction {
}
Instruction::Cast(value, _) => *value = f(*value),
Instruction::Not(value) => *value = f(*value),
Instruction::Truncate { value, bit_size: _, max_bit_size: _ } => {
Instruction::Truncate { value, bit_size: _, } => {
*value = f(*value);
}
Instruction::Constrain(lhs, rhs, assert_message) => {
Expand Down Expand Up @@ -908,8 +907,8 @@ impl Instruction {

try_optimize_array_set_from_previous_get(dfg, *array_id, *index_id, *value)
}
Instruction::Truncate { value, bit_size, max_bit_size } => {
if bit_size == max_bit_size {
Instruction::Truncate { value, bit_size } => {
if *bit_size == FieldElement::max_num_bits() {
return SimplifiedTo(*value);
}
if let Some((numeric_constant, typ)) = dfg.get_numeric_constant_with_type(*value) {
Expand All @@ -920,7 +919,7 @@ impl Instruction {
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 {
if src_bit_size <= bit_size {
SimplifiedTo(*value)
} else {
None
Expand Down
2 changes: 0 additions & 2 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ impl Binary {
Instruction::Truncate {
value: self.lhs,
bit_size,
max_bit_size: lhs_type.bit_size(),
},
);
}
Expand Down Expand Up @@ -305,7 +304,6 @@ impl Binary {
Instruction::Truncate {
value,
bit_size: num_bits,
max_bit_size: lhs_type.bit_size(),
},
);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_evaluator/src/ssa/ir/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,9 @@ fn display_instruction_inner(
}
Instruction::Cast(lhs, typ) => writeln!(f, "cast {} as {typ}", show(*lhs)),
Instruction::Not(rhs) => writeln!(f, "not {}", show(*rhs)),
Instruction::Truncate { value, bit_size, max_bit_size } => {
Instruction::Truncate { value, bit_size } => {
let value = show(*value);
writeln!(f, "truncate {value} to {bit_size} bits, max_bit_size: {max_bit_size}",)
writeln!(f, "truncate {value} to {bit_size} bits",)
}
Instruction::Constrain(lhs, rhs, error) => {
write!(f, "constrain {} == {}", show(*lhs), show(*rhs))?;
Expand Down
9 changes: 4 additions & 5 deletions compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl Context<'_> {
// Unchecked mul as this is a wrapping operation that we later truncate
let result =
self.insert_binary(lhs_field, BinaryOp::Mul { unchecked: true }, pow_field);
let result = self.insert_truncate(result, bit_size, max_bit);
let result = self.insert_truncate(result, bit_size);
self.insert_cast(result, typ)
}
}
Expand Down Expand Up @@ -184,7 +184,7 @@ impl Context<'_> {
BinaryOp::Add { unchecked: true },
lhs_as_field,
);
let one_complement = self.insert_truncate(one_complement, bit_size, bit_size + 1);
let one_complement = self.insert_truncate(one_complement, bit_size);
let one_complement = self.insert_cast(one_complement, NumericType::signed(bit_size));
// Performs the division on the 1-complement (or the operand if positive)
let shifted_complement = self.insert_binary(one_complement, BinaryOp::Div, pow);
Expand All @@ -201,7 +201,7 @@ impl Context<'_> {
BinaryOp::Sub { unchecked: true },
lhs_sign_as_int,
);
self.insert_truncate(shifted, bit_size, bit_size + 1)
self.insert_truncate(shifted, bit_size)
}
}

Expand Down Expand Up @@ -280,9 +280,8 @@ impl Context<'_> {
&mut self,
value: ValueId,
bit_size: u32,
max_bit_size: u32,
) -> ValueId {
self.insert_instruction(Instruction::Truncate { value, bit_size, max_bit_size }, None)
self.insert_instruction(Instruction::Truncate { value, bit_size }, None)
.first()
}

Expand Down
1 change: 0 additions & 1 deletion compiler/noirc_evaluator/src/ssa/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ pub(crate) enum ParsedInstruction {
target: Identifier,
value: ParsedValue,
bit_size: u32,
max_bit_size: u32,
},
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,9 @@ impl Translator {
let address = self.translate_value(address)?;
self.builder.insert_store(address, value);
}
ParsedInstruction::Truncate { target, value, bit_size, max_bit_size } => {
ParsedInstruction::Truncate { target, value, bit_size} => {
let value = self.translate_value(value)?;
let value_id = self.builder.insert_truncate(value, bit_size, max_bit_size);
let value_id = self.builder.insert_truncate(value, bit_size);
self.define_variable(target, value_id)?;
}
}
Expand Down
8 changes: 2 additions & 6 deletions compiler/noirc_evaluator/src/ssa/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,12 +506,8 @@ impl<'a> Parser<'a> {
let value = self.parse_value_or_error()?;
self.eat_or_error(Token::Keyword(Keyword::To))?;
let bit_size = self.eat_int_or_error()?.to_u128() as u32;
self.eat_or_error(Token::Keyword(Keyword::Bits))?;
self.eat_or_error(Token::Comma)?;
self.eat_or_error(Token::Keyword(Keyword::MaxBitSize))?;
self.eat_or_error(Token::Colon)?;
let max_bit_size = self.eat_int_or_error()?.to_u128() as u32;
return Ok(ParsedInstruction::Truncate { target, value, bit_size, max_bit_size });
self.eat_or_error(Token::Keyword(Keyword::Bits))?;``
return Ok(ParsedInstruction::Truncate { target, value, bit_size });
}

if let Some(op) = self.eat_binary_op()? {
Expand Down
8 changes: 4 additions & 4 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ impl<'a> FunctionContext<'a> {
match operator {
BinaryOpKind::Add | BinaryOpKind::Subtract => {
// Result is computed modulo the bit size
let result = self.builder.insert_truncate(result, bit_size, bit_size + 1);
let result = self.builder.insert_truncate(result, bit_size);
let result = self.insert_safe_cast(
result,
NumericType::unsigned(bit_size),
Expand All @@ -396,7 +396,7 @@ impl<'a> FunctionContext<'a> {
// Result is computed modulo the bit size
let mut result =
self.builder.insert_cast(result, NumericType::unsigned(2 * bit_size));
result = self.builder.insert_truncate(result, bit_size, 2 * bit_size);
result = self.builder.insert_truncate(result, bit_size);

self.check_signed_overflow(result, lhs, rhs, operator, bit_size, location);
self.insert_safe_cast(result, result_type, location)
Expand Down Expand Up @@ -461,7 +461,7 @@ impl<'a> FunctionContext<'a> {
one,
Some("attempt to bit-shift with overflow".to_owned().into()),
);
self.builder.insert_truncate(result, bit_size, bit_size + 1)
self.builder.insert_truncate(result, bit_size)
}

/// Insert constraints ensuring that the operation does not overflow the bit size of the result
Expand Down Expand Up @@ -641,7 +641,7 @@ impl<'a> FunctionContext<'a> {
let incoming_type_size = self.builder.type_of_value(value).bit_size();
let target_type_size = typ.bit_size();
if target_type_size < incoming_type_size {
value = self.builder.insert_truncate(value, target_type_size, incoming_type_size);
value = self.builder.insert_truncate(value, target_type_size);
}

self.builder.insert_cast(value, typ)
Expand Down

0 comments on commit 59c33e5

Please sign in to comment.