diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 277373a6896..929197e8989 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -521,7 +521,7 @@ impl<'block> BrilligBlock<'block> { unreachable!("unsupported function call type {:?}", dfg[*func]) } }, - Instruction::Truncate { value, .. } => { + Instruction::Truncate { value, bit_size, .. } => { let result_ids = dfg.instruction_results(instruction_id); let destination_register = self.variables.define_register_variable( self.function_context, @@ -530,7 +530,11 @@ impl<'block> BrilligBlock<'block> { dfg, ); let source_register = self.convert_ssa_register_value(*value, dfg); - self.brillig_context.truncate_instruction(destination_register, source_register); + self.brillig_context.truncate_instruction( + destination_register, + source_register, + *bit_size, + ); } Instruction::Cast(value, target_type) => { let result_ids = dfg.instruction_results(instruction_id); diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 0260af13730..f210e189062 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -687,10 +687,19 @@ impl BrilligContext { &mut self, destination_of_truncated_value: RegisterIndex, value_to_truncate: RegisterIndex, + bit_size: u32, ) { - // Effectively a no-op because brillig already has implicit truncation on integer - // operations. We need only copy the value to it's destination. - self.mov_instruction(destination_of_truncated_value, value_to_truncate); + // The brillig VM performs all arithmetic operations modulo 2**bit_size + // So to truncate any value to a target bit size we can just issue a no-op arithmetic operation + // With bit size equal to target_bit_size + let zero_register = self.make_constant(Value::from(FieldElement::zero())); + self.binary_instruction( + value_to_truncate, + zero_register, + destination_of_truncated_value, + BrilligBinaryOp::Integer { op: BinaryIntOp::Add, bit_size }, + ); + self.deallocate_register(zero_register); } /// Emits a stop instruction