Skip to content

Commit f3243b7

Browse files
authored
feat: Add checks for bit size consistency on brillig gen (#4542)
# Description ## Problem\* Adds checks for brillig codegen for #4369 (Previously we only had consistency checks in SSA). ## Summary\* This checks have caught some inconsistencies in the process, including those that were caught manually in AztecProtocol/aztec-packages#5091 ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
1 parent 00d6494 commit f3243b7

9 files changed

Lines changed: 368 additions & 305 deletions

File tree

compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs

Lines changed: 100 additions & 109 deletions
Large diffs are not rendered by default.

compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block_variables.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet};
33
use crate::{
44
brillig::brillig_ir::{
55
brillig_variable::{BrilligArray, BrilligVariable, BrilligVector, SingleAddrVariable},
6-
BrilligContext, BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
6+
BrilligContext,
77
},
88
ssa::ir::{
99
basic_block::BasicBlockId,
@@ -13,7 +13,7 @@ use crate::{
1313
},
1414
};
1515

16-
use super::brillig_fn::FunctionContext;
16+
use super::brillig_fn::{get_bit_size_from_ssa_type, FunctionContext};
1717

1818
#[derive(Debug, Default)]
1919
pub(crate) struct BlockVariables {
@@ -189,21 +189,10 @@ pub(crate) fn allocate_value(
189189
let typ = dfg.type_of_value(value_id);
190190

191191
match typ {
192-
Type::Numeric(numeric_type) => BrilligVariable::SingleAddr(SingleAddrVariable {
193-
address: brillig_context.allocate_register(),
194-
bit_size: numeric_type.bit_size(),
195-
}),
196-
Type::Reference(_) => BrilligVariable::SingleAddr(SingleAddrVariable {
197-
address: brillig_context.allocate_register(),
198-
bit_size: BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
199-
}),
200-
Type::Function => {
201-
// NB. function references are converted to a constant when
202-
// translating from SSA to Brillig (to allow for debugger
203-
// instrumentation to work properly)
192+
Type::Numeric(_) | Type::Reference(_) | Type::Function => {
204193
BrilligVariable::SingleAddr(SingleAddrVariable {
205194
address: brillig_context.allocate_register(),
206-
bit_size: 32,
195+
bit_size: get_bit_size_from_ssa_type(&typ),
207196
})
208197
}
209198
Type::Array(item_typ, elem_count) => {

compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use acvm::FieldElement;
21
use iter_extended::vecmap;
32

43
use crate::{
@@ -11,7 +10,7 @@ use crate::{
1110
basic_block::BasicBlockId,
1211
function::{Function, FunctionId},
1312
post_order::PostOrder,
14-
types::{NumericType, Type},
13+
types::Type,
1514
value::ValueId,
1615
},
1716
};
@@ -116,11 +115,12 @@ impl FunctionContext {
116115

117116
pub(crate) fn get_bit_size_from_ssa_type(typ: &Type) -> u32 {
118117
match typ {
119-
Type::Numeric(num_type) => match num_type {
120-
NumericType::Signed { bit_size } | NumericType::Unsigned { bit_size } => *bit_size,
121-
NumericType::NativeField => FieldElement::max_num_bits(),
122-
},
118+
Type::Numeric(num_type) => num_type.bit_size(),
123119
Type::Reference(_) => BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
124-
_ => unreachable!("ICE bitwise not on a non numeric type"),
120+
// NB. function references are converted to a constant when
121+
// translating from SSA to Brillig (to allow for debugger
122+
// instrumentation to work properly)
123+
Type::Function => 32,
124+
_ => unreachable!("ICE bit size not on a non numeric type"),
125125
}
126126
}

compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use acvm::brillig_vm::brillig::{BinaryIntOp, MemoryAddress};
1+
use acvm::brillig_vm::brillig::BinaryIntOp;
22

3-
use crate::brillig::brillig_ir::brillig_variable::{BrilligVariable, BrilligVector};
3+
use crate::brillig::brillig_ir::brillig_variable::{
4+
BrilligVariable, BrilligVector, SingleAddrVariable,
5+
};
46

57
use super::brillig_block::BrilligBlock;
68

@@ -26,19 +28,19 @@ impl<'block> BrilligBlock<'block> {
2628
self.brillig_context.copy_array_instruction(
2729
source_vector.pointer,
2830
target_vector.pointer,
29-
source_vector.size,
31+
SingleAddrVariable::new_usize(source_vector.size),
3032
);
3133

3234
for (index, variable) in variables_to_insert.iter().enumerate() {
3335
let target_index = self.brillig_context.make_usize_constant(index.into());
3436
self.brillig_context.memory_op(
35-
target_index,
37+
target_index.address,
3638
source_vector.size,
37-
target_index,
39+
target_index.address,
3840
BinaryIntOp::Add,
3941
);
4042
self.store_variable_in_array(target_vector.pointer, target_index, *variable);
41-
self.brillig_context.deallocate_register(target_index);
43+
self.brillig_context.deallocate_single_addr(target_index);
4244
}
4345
}
4446

@@ -72,14 +74,14 @@ impl<'block> BrilligBlock<'block> {
7274
self.brillig_context.copy_array_instruction(
7375
source_vector.pointer,
7476
destination_copy_pointer,
75-
source_vector.size,
77+
SingleAddrVariable::new_usize(source_vector.size),
7678
);
7779

7880
// Then we write the items to insert at the start
7981
for (index, variable) in variables_to_insert.iter().enumerate() {
8082
let target_index = self.brillig_context.make_usize_constant(index.into());
8183
self.store_variable_in_array(target_vector.pointer, target_index, *variable);
82-
self.brillig_context.deallocate_register(target_index);
84+
self.brillig_context.deallocate_single_addr(target_index);
8385
}
8486

8587
self.brillig_context.deallocate_register(destination_copy_pointer);
@@ -115,13 +117,13 @@ impl<'block> BrilligBlock<'block> {
115117
self.brillig_context.copy_array_instruction(
116118
source_copy_pointer,
117119
target_vector.pointer,
118-
target_vector.size,
120+
SingleAddrVariable::new_usize(target_vector.size),
119121
);
120122

121123
for (index, variable) in removed_items.iter().enumerate() {
122124
let target_index = self.brillig_context.make_usize_constant(index.into());
123125
self.retrieve_variable_from_array(source_vector.pointer, target_index, *variable);
124-
self.brillig_context.deallocate_register(target_index);
126+
self.brillig_context.deallocate_single_addr(target_index);
125127
}
126128

127129
self.brillig_context.deallocate_register(source_copy_pointer);
@@ -148,27 +150,27 @@ impl<'block> BrilligBlock<'block> {
148150
self.brillig_context.copy_array_instruction(
149151
source_vector.pointer,
150152
target_vector.pointer,
151-
target_vector.size,
153+
SingleAddrVariable::new_usize(target_vector.size),
152154
);
153155

154156
for (index, variable) in removed_items.iter().enumerate() {
155157
let target_index = self.brillig_context.make_usize_constant(index.into());
156158
self.brillig_context.memory_op(
157-
target_index,
159+
target_index.address,
158160
target_vector.size,
159-
target_index,
161+
target_index.address,
160162
BinaryIntOp::Add,
161163
);
162164
self.retrieve_variable_from_array(source_vector.pointer, target_index, *variable);
163-
self.brillig_context.deallocate_register(target_index);
165+
self.brillig_context.deallocate_single_addr(target_index);
164166
}
165167
}
166168

167169
pub(crate) fn slice_insert_operation(
168170
&mut self,
169171
target_vector: BrilligVector,
170172
source_vector: BrilligVector,
171-
index: MemoryAddress,
173+
index: SingleAddrVariable,
172174
items: &[BrilligVariable],
173175
) {
174176
// First we need to allocate the target vector incrementing the size by items.len()
@@ -193,7 +195,7 @@ impl<'block> BrilligBlock<'block> {
193195
let source_pointer_at_index = self.brillig_context.allocate_register();
194196
self.brillig_context.memory_op(
195197
source_vector.pointer,
196-
index,
198+
index.address,
197199
source_pointer_at_index,
198200
BinaryIntOp::Add,
199201
);
@@ -202,7 +204,7 @@ impl<'block> BrilligBlock<'block> {
202204
let target_pointer_after_index = self.brillig_context.allocate_register();
203205
self.brillig_context.memory_op(
204206
target_vector.pointer,
205-
index,
207+
index.address,
206208
target_pointer_after_index,
207209
BinaryIntOp::Add,
208210
);
@@ -214,21 +216,31 @@ impl<'block> BrilligBlock<'block> {
214216

215217
// Compute the number of elements to the right of the index
216218
let item_count = self.brillig_context.allocate_register();
217-
self.brillig_context.memory_op(source_vector.size, index, item_count, BinaryIntOp::Sub);
219+
self.brillig_context.memory_op(
220+
source_vector.size,
221+
index.address,
222+
item_count,
223+
BinaryIntOp::Sub,
224+
);
218225

219226
// Copy the elements to the right of the index
220227
self.brillig_context.copy_array_instruction(
221228
source_pointer_at_index,
222229
target_pointer_after_index,
223-
item_count,
230+
SingleAddrVariable::new_usize(item_count),
224231
);
225232

226233
// Write the items to insert starting at the index
227234
for (subitem_index, variable) in items.iter().enumerate() {
228235
let target_index = self.brillig_context.make_usize_constant(subitem_index.into());
229-
self.brillig_context.memory_op(target_index, index, target_index, BinaryIntOp::Add);
236+
self.brillig_context.memory_op(
237+
target_index.address,
238+
index.address,
239+
target_index.address,
240+
BinaryIntOp::Add,
241+
);
230242
self.store_variable_in_array(target_vector.pointer, target_index, *variable);
231-
self.brillig_context.deallocate_register(target_index);
243+
self.brillig_context.deallocate_single_addr(target_index);
232244
}
233245

234246
self.brillig_context.deallocate_register(source_pointer_at_index);
@@ -240,7 +252,7 @@ impl<'block> BrilligBlock<'block> {
240252
&mut self,
241253
target_vector: BrilligVector,
242254
source_vector: BrilligVector,
243-
index: MemoryAddress,
255+
index: SingleAddrVariable,
244256
removed_items: &[BrilligVariable],
245257
) {
246258
// First we need to allocate the target vector decrementing the size by removed_items.len()
@@ -265,7 +277,7 @@ impl<'block> BrilligBlock<'block> {
265277
let source_pointer_after_index = self.brillig_context.allocate_register();
266278
self.brillig_context.memory_op(
267279
source_vector.pointer,
268-
index,
280+
index.address,
269281
source_pointer_after_index,
270282
BinaryIntOp::Add,
271283
);
@@ -279,29 +291,39 @@ impl<'block> BrilligBlock<'block> {
279291
let target_pointer_at_index = self.brillig_context.allocate_register();
280292
self.brillig_context.memory_op(
281293
target_vector.pointer,
282-
index,
294+
index.address,
283295
target_pointer_at_index,
284296
BinaryIntOp::Add,
285297
);
286298

287299
// Compute the number of elements to the right of the index
288300
let item_count = self.brillig_context.allocate_register();
289-
self.brillig_context.memory_op(source_vector.size, index, item_count, BinaryIntOp::Sub);
301+
self.brillig_context.memory_op(
302+
source_vector.size,
303+
index.address,
304+
item_count,
305+
BinaryIntOp::Sub,
306+
);
290307
self.brillig_context.usize_op_in_place(item_count, BinaryIntOp::Sub, removed_items.len());
291308

292309
// Copy the elements to the right of the index
293310
self.brillig_context.copy_array_instruction(
294311
source_pointer_after_index,
295312
target_pointer_at_index,
296-
item_count,
313+
SingleAddrVariable::new_usize(item_count),
297314
);
298315

299316
// Get the removed items
300317
for (subitem_index, variable) in removed_items.iter().enumerate() {
301318
let target_index = self.brillig_context.make_usize_constant(subitem_index.into());
302-
self.brillig_context.memory_op(target_index, index, target_index, BinaryIntOp::Add);
319+
self.brillig_context.memory_op(
320+
target_index.address,
321+
index.address,
322+
target_index.address,
323+
BinaryIntOp::Add,
324+
);
303325
self.retrieve_variable_from_array(source_vector.pointer, target_index, *variable);
304-
self.brillig_context.deallocate_register(target_index);
326+
self.brillig_context.deallocate_single_addr(target_index);
305327
}
306328

307329
self.brillig_context.deallocate_register(source_pointer_after_index);
@@ -592,7 +614,10 @@ mod tests {
592614
address: context.allocate_register(),
593615
bit_size: BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
594616
};
595-
let index_to_insert = context.allocate_register();
617+
let index_to_insert = SingleAddrVariable::new(
618+
context.allocate_register(),
619+
BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
620+
);
596621

597622
// Cast the source array to a vector
598623
let source_vector = context.array_to_vector(&array_variable);
@@ -710,7 +735,10 @@ mod tests {
710735
size: array.len(),
711736
rc: context.allocate_register(),
712737
};
713-
let index_to_insert = context.allocate_register();
738+
let index_to_insert = SingleAddrVariable::new(
739+
context.allocate_register(),
740+
BRILLIG_MEMORY_ADDRESSING_BIT_SIZE,
741+
);
714742

715743
// Cast the source array to a vector
716744
let source_vector = context.array_to_vector(&array_variable);

0 commit comments

Comments
 (0)