diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs index d07b411f5a1..7a8abe7e482 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs @@ -84,28 +84,37 @@ impl BrilligContext { output: HeapArray { pointer: target_vector.pointer, size: limb_count }, }); - let limb_field = SingleAddrVariable::new(self.allocate_register(), F::max_num_bits()); - let limb_casted = SingleAddrVariable::new(self.allocate_register(), limb_bit_size); - if limb_bit_size != F::max_num_bits() { - self.codegen_loop(target_vector.size, |ctx, iterator_register| { - // Read the limb - ctx.codegen_array_get(target_vector.pointer, iterator_register, limb_field.address); - // Cast it - ctx.cast_instruction(limb_casted, limb_field); - // Write it - ctx.codegen_array_set( - target_vector.pointer, - iterator_register, - limb_casted.address, - ); - }); + let end_pointer = self.allocate_register(); + let temporary_register = self.allocate_register(); + + self.memory_op_instruction( + target_vector.pointer, + target_vector.size, + end_pointer, + BrilligBinaryOp::Add, + ); + + self.codegen_for_loop( + Some(target_vector.pointer), + end_pointer, + None, + |ctx, item_pointer| { + ctx.load_instruction(temporary_register, item_pointer.address); + + ctx.cast( + SingleAddrVariable::new(temporary_register, limb_bit_size), + SingleAddrVariable::new(temporary_register, F::max_num_bits()), + ); + + ctx.store_instruction(item_pointer.address, temporary_register); + }, + ); + + self.deallocate_register(end_pointer); + self.deallocate_register(temporary_register); } - // Deallocate our temporary registers - self.deallocate_single_addr(limb_field); - self.deallocate_single_addr(limb_casted); - if big_endian { self.codegen_reverse_vector_in_place(target_vector); }