Skip to content
56 changes: 31 additions & 25 deletions compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/call/blackbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,17 @@ pub(super) fn simplify_msm(
var_points.push(result_is_infinity);
}
// Construct the simplified MSM expression
let typ = Type::Array(Arc::new(vec![Type::field()]), var_scalars.len() as u32);
let typ = Type::Array(
Arc::new(vec![Type::field(), Type::field()]),
var_scalars.len() as u32 / 2,
);
let scalars = Instruction::MakeArray { elements: var_scalars.into(), typ };
let scalars =
dfg.insert_instruction_and_results(scalars, block, None, call_stack).first();
let typ = Type::Array(Arc::new(vec![Type::field()]), var_points.len() as u32);
let typ = Type::Array(
Arc::new(vec![Type::field(), Type::field(), Type::bool()]),
var_points.len() as u32 / 3,
);
let points = Instruction::MakeArray { elements: var_points.into(), typ };
let points =
dfg.insert_instruction_and_results(points, block, None, call_stack).first();
Expand Down Expand Up @@ -367,8 +373,8 @@ mod multi_scalar_mul {
let src = r#"
acir(inline) fn main f0 {
b0():
v0 = make_array [Field 2, Field 3, Field 5, Field 5] : [Field; 4]
v1 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 6]
v0 = make_array [Field 2, Field 3, Field 5, Field 5] : [(Field, Field); 2]
v1 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0] : [(Field, Field, u1); 2]
v2 = call multi_scalar_mul (v1, v0) -> [(Field, Field, u1); 1]
return v2
}"#;
Expand All @@ -377,10 +383,10 @@ mod multi_scalar_mul {
assert_ssa_snapshot!(ssa, @r"
acir(inline) fn main f0 {
b0():
v3 = make_array [Field 2, Field 3, Field 5, Field 5] : [Field; 4]
v7 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 6]
v11 = make_array [Field 1478523918288173385110236399861791147958001875200066088686689589556927843200, Field 700144278551281040379388961242974992655630750193306467120985766322057145630, u1 0] : [(Field, Field, u1); 1]
return v11
v3 = make_array [Field 2, Field 3, Field 5, Field 5] : [(Field, Field); 2]
v7 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0] : [(Field, Field, u1); 2]
v10 = make_array [Field 1478523918288173385110236399861791147958001875200066088686689589556927843200, Field 700144278551281040379388961242974992655630750193306467120985766322057145630, u1 0] : [(Field, Field, u1); 1]
return v10
}
");
}
Expand All @@ -391,10 +397,10 @@ mod multi_scalar_mul {
let src = r#"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
v2 = make_array [v0, Field 0, Field 0, Field 0, v0, Field 0] : [Field; 6]
v2 = make_array [v0, Field 0, Field 0, Field 0, v0, Field 0] : [(Field, Field); 3]
v3 = make_array [
Field 0, Field 0, Field 1, v0, v1, Field 0, Field 1, v0, Field 0] : [Field; 9]
v4 = call multi_scalar_mul (v3, v2) -> [Field; 3]
Field 0, Field 0, u1 1, v0, v1, u1 0, Field 1, v0, u1 0] : [(Field, Field, u1); 3]
v4 = call multi_scalar_mul (v3, v2) -> [(Field, Field, u1); 1]

return v4

Expand All @@ -404,12 +410,12 @@ mod multi_scalar_mul {
assert_ssa_snapshot!(ssa, @r"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
v3 = make_array [v0, Field 0, Field 0, Field 0, v0, Field 0] : [Field; 6]
v5 = make_array [Field 0, Field 0, Field 1, v0, v1, Field 0, Field 1, v0, Field 0] : [Field; 9]
v6 = make_array [v0, Field 0] : [Field; 2]
v7 = make_array [Field 1, v0, Field 0] : [Field; 3]
v9 = call multi_scalar_mul(v7, v6) -> [Field; 3]
return v9
v3 = make_array [v0, Field 0, Field 0, Field 0, v0, Field 0] : [(Field, Field); 3]
v7 = make_array [Field 0, Field 0, u1 1, v0, v1, u1 0, Field 1, v0, u1 0] : [(Field, Field, u1); 3]
v8 = make_array [v0, Field 0] : [(Field, Field); 1]
v9 = make_array [Field 1, v0, u1 0] : [(Field, Field, u1); 1]
v11 = call multi_scalar_mul(v9, v8) -> [(Field, Field, u1); 1]
return v11
}
");
}
Expand All @@ -420,22 +426,22 @@ mod multi_scalar_mul {
let src = r#"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
v2 = make_array [Field 1, Field 0, v0, Field 0, Field 2, Field 0] : [Field; 6]
v2 = make_array [Field 1, Field 0, v0, Field 0, Field 2, Field 0] : [(Field, Field); 3]
v3 = make_array [
Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, v0, v1, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 9]
v4 = call multi_scalar_mul (v3, v2) -> [Field; 3]
Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0, v0, v1, u1 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0] : [(Field, Field, u1); 3]
v4 = call multi_scalar_mul (v3, v2) -> [(Field, Field, u1); 1]
return v4
}"#;
let ssa = Ssa::from_str_simplifying(src).unwrap();
//First and last scalar/point are constant, so we should be left with the msm of the middle point and the folded constant point
assert_ssa_snapshot!(ssa, @r"
acir(inline) fn main f0 {
b0(v0: Field, v1: Field):
v5 = make_array [Field 1, Field 0, v0, Field 0, Field 2, Field 0] : [Field; 6]
v7 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0, v0, v1, Field 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, Field 0] : [Field; 9]
v8 = make_array [v0, Field 0, Field 1, Field 0] : [Field; 4]
v12 = make_array [v0, v1, Field 0, Field -3227352362257037263902424173275354266044964400219754872043023745437788450996, Field 8902249110305491597038405103722863701255802573786510474664632793109847672620, u1 0] : [Field; 6]
v14 = call multi_scalar_mul(v12, v8) -> [Field; 3]
v5 = make_array [Field 1, Field 0, v0, Field 0, Field 2, Field 0] : [(Field, Field); 3]
v8 = make_array [Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0, v0, v1, u1 0, Field 1, Field 17631683881184975370165255887551781615748388533673675138860, u1 0] : [(Field, Field, u1); 3]
v9 = make_array [v0, Field 0, Field 1, Field 0] : [(Field, Field); 2]
v12 = make_array [v0, v1, u1 0, Field -3227352362257037263902424173275354266044964400219754872043023745437788450996, Field 8902249110305491597038405103722863701255802573786510474664632793109847672620, u1 0] : [(Field, Field, u1); 2]
v14 = call multi_scalar_mul(v12, v9) -> [(Field, Field, u1); 1]
return v14
}
");
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,7 +1511,7 @@ mod test {
}

brillig(inline) fn one f1 {
b0(v0: Field, v1: i32, v2: i32, v3: Field):
b0(v0: Field, v1: i32, v2: Field, v3: i32):
v4 = make_array [v0, v1, v2, v3] : [(Field, i32); 2]
return v4
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ mod tests {
let src = r#"
acir(inline) fn main f0 {
b0(v0: u32):
v1 = make_array [f1] : [function; 0]
v1 = make_array [f1] : [function; 1]
v2 = array_set v1, index u32 0, value f2
return v0
}
Expand Down
107 changes: 107 additions & 0 deletions compiler/noirc_evaluator/src/ssa/validation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//! - Check that the input values of certain instructions matches that instruction's constraint
//! At the moment, only [Instruction::Binary], [Instruction::ArrayGet], and [Instruction::ArraySet]
//! are type checked.
use core::panic;

use acvm::{AcirField, FieldElement};
use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet};

Expand Down Expand Up @@ -258,6 +260,51 @@ impl<'f> Validator<'f> {
);
}
}
Instruction::MakeArray { elements, typ: _ } => {
let results = dfg.instruction_results(instruction);
assert_eq!(results.len(), 1, "MakeArray must return exactly one value");

let result_type = dfg.type_of_value(results[0]);

let composite_type = match result_type {
Type::Array(composite_type, length) => {
let array_flattened_length = composite_type.len() * length as usize;
if elements.len() != array_flattened_length {
panic!(
"MakeArray returns an array of flattened length {}, but it has {} elements",
array_flattened_length,
elements.len()
);
}
composite_type
}
Type::Slice(composite_type) => {
if elements.len() % composite_type.len() != 0 {
panic!(
"MakeArray slice has {} elements but composite type has {} types which don't divide the number of elements",
elements.len(),
composite_type.len()
);
}
composite_type
}
_ => {
panic!("MakeArray must return an array or slice type, not {result_type}");
}
};

let composite_type_len = composite_type.len();
for (index, element) in elements.iter().enumerate() {
let element_type = dfg.type_of_value(*element);
let expected_type = &composite_type[index % composite_type_len];
if &element_type != expected_type {
panic!(
"MakeArray has incorrect element type at index {index}: expected {}, got {}",
expected_type, element_type
);
}
}
}
_ => (),
}
}
Expand Down Expand Up @@ -603,4 +650,64 @@ mod tests {
";
let _ = Ssa::from_str(src).unwrap();
}

#[test]
#[should_panic(
expected = "MakeArray returns an array of flattened length 2, but it has 3 elements"
)]
fn make_array_returns_incorrect_length() {
let src = "
acir(inline) fn main f0 {
b0():
v0 = make_array [u8 1, u8 2, u8 3] : [u8; 2]
return v0
}
";
let _ = Ssa::from_str(src).unwrap();
}

#[test]
#[should_panic(
expected = "MakeArray returns an array of flattened length 4, but it has 3 elements"
)]
fn make_array_returns_incorrect_length_composite_type() {
let src = "
acir(inline) fn main f0 {
b0():
v0 = make_array [u8 1, u8 2, u8 3] : [(u8, u8); 2]
return v0
}
";
let _ = Ssa::from_str(src).unwrap();
}

#[test]
#[should_panic(
expected = "MakeArray slice has 3 elements but composite type has 2 types which don't divide the number of elements"
)]
fn make_array_slice_returns_incorrect_length() {
let src = "
acir(inline) fn main f0 {
b0():
v0 = make_array [u8 1, u8 2, u8 3] : [(u8, u8)]
return v0
}
";
let _ = Ssa::from_str(src).unwrap();
}

#[test]
#[should_panic(
expected = "MakeArray has incorrect element type at index 1: expected u8, got Field"
)]
fn make_array_has_incorrect_element_type() {
let src = "
acir(inline) fn main f0 {
b0():
v0 = make_array [u8 1, Field 2, u8 3, u8 4] : [(u8, u8); 2]
return v0
}
";
let _ = Ssa::from_str(src).unwrap();
}
Comment thread
asterite marked this conversation as resolved.
}
Loading
Loading