Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
277 changes: 145 additions & 132 deletions compiler/noirc_evaluator/src/acir/tests/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -1,162 +1,175 @@
use acvm::{FieldElement, acir::circuit::ExpressionWidth};

use crate::{
acir::GeneratedAcir,
brillig::BrilligOptions,
ssa::{ir::instruction::Intrinsic, ssa_gen::Ssa},
};
use crate::acir::tests::ssa_to_acir_program;

#[test]
fn slice_push_back_not_affected_by_predicate() {
let func_with_pred = &get_slice_intrinsic_acir(
"v9, v10",
&Intrinsic::SlicePushBack.to_string(),
", Field 1, v4) -> (u32, [(Field, [Field; 2])])",
true,
)[0];
let func_no_pred = &get_slice_intrinsic_acir(
"v9, v10",
&Intrinsic::SlicePushBack.to_string(),
", Field 1, v4) -> (u32, [(Field, [Field; 2])])",
false,
)[0];
assert_eq!(func_with_pred.current_witness_index(), func_no_pred.current_witness_index());
assert_eq!(func_with_pred.opcodes(), func_no_pred.opcodes());
let src_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
enable_side_effects v1
v9, v10 = call slice_push_back(u32 1, v7, Field 1, v4) -> (u32, [(Field, [Field; 2])])
return
}
";
let src_no_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
v9, v10 = call slice_push_back(u32 1, v7, Field 1, v4) -> (u32, [(Field, [Field; 2])])
return
}
";

let program_side_effects = ssa_to_acir_program(src_side_effects);
let program_no_side_effects = ssa_to_acir_program(src_no_side_effects);
assert_eq!(program_side_effects, program_no_side_effects);
}

#[test]
fn slice_push_front_not_affected_by_predicate() {
let func_with_pred = &get_slice_intrinsic_acir(
"v9, v10",
&Intrinsic::SlicePushFront.to_string(),
", Field 1, v4) -> (u32, [(Field, [Field; 2])])",
true,
)[0];
let func_no_pred = &get_slice_intrinsic_acir(
"v9, v10",
&Intrinsic::SlicePushFront.to_string(),
", Field 1, v4) -> (u32, [(Field, [Field; 2])])",
false,
)[0];
assert_eq!(func_with_pred.current_witness_index(), func_no_pred.current_witness_index());
assert_eq!(func_with_pred.opcodes(), func_no_pred.opcodes());
let src_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
enable_side_effects v1
v9, v10 = call slice_push_front(u32 1, v7, Field 1, v4) -> (u32, [(Field, [Field; 2])])
return
}
";
let src_no_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
v9, v10 = call slice_push_front(u32 1, v7, Field 1, v4) -> (u32, [(Field, [Field; 2])])
return
}
";

let program_side_effects = ssa_to_acir_program(src_side_effects);
let program_no_side_effects = ssa_to_acir_program(src_no_side_effects);
assert_eq!(program_side_effects, program_no_side_effects);
}

#[test]
fn slice_pop_back_not_affected_by_predicate() {
let func_with_pred = &get_slice_intrinsic_acir(
"v9, v10, v11, v12",
&Intrinsic::SlicePopBack.to_string(),
") -> (u32, [(Field, [Field; 2])], Field, [Field; 2])",
true,
)[0];
let func_no_pred = &get_slice_intrinsic_acir(
"v9, v10, v11, v12",
&Intrinsic::SlicePopBack.to_string(),
") -> (u32, [(Field, [Field; 2])], Field, [Field; 2])",
false,
)[0];
assert_eq!(func_with_pred.current_witness_index(), func_no_pred.current_witness_index());
assert_eq!(func_with_pred.opcodes(), func_no_pred.opcodes());
let src_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
enable_side_effects v1
v9, v10, v11, v12 = call slice_pop_back(u32 1, v7) -> (u32, [(Field, [Field; 2])], Field, [Field; 2])
return
}
";
let src_no_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
v9, v10, v11, v12 = call slice_pop_back(u32 1, v7) -> (u32, [(Field, [Field; 2])], Field, [Field; 2])
return
}
";

let program_side_effects = ssa_to_acir_program(src_side_effects);
let program_no_side_effects = ssa_to_acir_program(src_no_side_effects);
assert_eq!(program_side_effects, program_no_side_effects);
}

#[test]
fn slice_pop_front_not_affected_by_predicate() {
let func_with_pred = &get_slice_intrinsic_acir(
"v9, v10, v11, v12",
&Intrinsic::SlicePopFront.to_string(),
") -> (Field, [Field; 2], u32, [(Field, [Field; 2])])",
true,
)[0];
let func_no_pred = &get_slice_intrinsic_acir(
"v9, v10, v11, v12",
&Intrinsic::SlicePopFront.to_string(),
") -> (Field, [Field; 2], u32, [(Field, [Field; 2])])",
false,
)[0];
assert_eq!(func_with_pred.current_witness_index(), func_no_pred.current_witness_index());
assert_eq!(func_with_pred.opcodes(), func_no_pred.opcodes());
let src_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
enable_side_effects v1
v9, v10, v11, v12 = call slice_pop_front(u32 1, v7) -> (Field, [Field; 2], u32, [(Field, [Field; 2])])
return
}
";
let src_no_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
v9, v10, v11, v12 = call slice_pop_front(u32 1, v7) -> (Field, [Field; 2], u32, [(Field, [Field; 2])])
return
}
";

let program_side_effects = ssa_to_acir_program(src_side_effects);
let program_no_side_effects = ssa_to_acir_program(src_no_side_effects);
assert_eq!(program_side_effects, program_no_side_effects);
}

#[test]
fn slice_insert_affected_by_predicate() {
let func_with_pred = &get_slice_intrinsic_acir(
"v9, v10",
&Intrinsic::SliceInsert.to_string(),
", u32 1, Field 1, v4) -> (u32, [(Field, [Field; 2])])",
true,
)[0];
let func_no_pred = &get_slice_intrinsic_acir(
"v9, v10",
&Intrinsic::SliceInsert.to_string(),
", u32 1, Field 1, v4) -> (u32, [(Field, [Field; 2])])",
false,
)[0];
assert_ne!(func_with_pred.current_witness_index(), func_no_pred.current_witness_index());
assert_ne!(func_with_pred.opcodes(), func_no_pred.opcodes());
let src_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
enable_side_effects v1
v9, v10 = call slice_insert(u32 1, v7, u32 1, Field 1, v4) -> (u32, [(Field, [Field; 2])])
return
}
";
let src_no_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
v9, v10 = call slice_insert(u32 1, v7, u32 1, Field 1, v4) -> (u32, [(Field, [Field; 2])])
return
}
";

let program_side_effects = ssa_to_acir_program(src_side_effects);
let program_no_side_effects = ssa_to_acir_program(src_no_side_effects);
assert_ne!(program_side_effects, program_no_side_effects);
}

#[test]
fn slice_remove_affected_by_predicate() {
let func_with_pred = &get_slice_intrinsic_acir(
"v9, v10, v11, v12",
&Intrinsic::SliceRemove.to_string(),
", u32 1) -> (u32, [(Field, [Field; 2])], Field, [Field; 2])",
true,
)[0];
let func_no_pred = &get_slice_intrinsic_acir(
"v9, v10, v11, v12",
&Intrinsic::SliceRemove.to_string(),
", u32 1) -> (u32, [(Field, [Field; 2])], Field, [Field; 2])",
false,
)[0];
assert_ne!(func_with_pred.current_witness_index(), func_no_pred.current_witness_index());
assert_ne!(func_with_pred.opcodes(), func_no_pred.opcodes());
}

/// Helper method to set up the SSA for unit tests on whether slice intrinsics
/// are affected by the ACIR gen predicate.
fn get_slice_intrinsic_src(
return_values: &str,
intrinsic_name: &str,
args_and_return_type: &str,
with_side_effects: bool,
) -> String {
let side_effects = if with_side_effects { "enable_side_effects v1\n" } else { "" };
format!(
"
acir(inline) predicate_pure fn main f0 {{
let src_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
{side_effects}
{return_values} = call {intrinsic_name}(u32 1, v7{args_and_return_type}
enable_side_effects v1
v9, v10, v11, v12 = call slice_remove(u32 1, v7, u32 1) -> (u32, [(Field, [Field; 2])], Field, [Field; 2])
return
}}
"
)
}

/// Helper for fetching the ACIR for the SSA specified in [get_slice_intrinsic_src].
/// This helper assumes we have a single main function we are testing against.
fn get_slice_intrinsic_acir(
return_values: &str,
intrinsic_name: &str,
args_and_return_type: &str,
with_side_effects: bool,
) -> Vec<GeneratedAcir<FieldElement>> {
let src = get_slice_intrinsic_src(
return_values,
intrinsic_name,
args_and_return_type,
with_side_effects,
);
let ssa = Ssa::from_str(&src).unwrap();
let brillig = ssa.to_brillig(&BrilligOptions::default());
}
";
let src_no_side_effects = "
acir(inline) predicate_pure fn main f0 {
b0(v0: u32, v1: u1):
v4 = make_array [Field 2, Field 3] : [Field; 2]
v5 = make_array [Field 1, v4] : [(Field, [Field; 2])]
v7 = array_set v5, index v0, value Field 4
v9, v10, v11, v12 = call slice_remove(u32 1, v7, u32 1) -> (u32, [(Field, [Field; 2])], Field, [Field; 2])
return
}
";

let (acir_functions_with_pred, _brillig_functions, _) = ssa
.into_acir(&brillig, &BrilligOptions::default(), ExpressionWidth::default())
.expect("Should compile manually written SSA into ACIR");
acir_functions_with_pred
let program_side_effects = ssa_to_acir_program(src_side_effects);
let program_no_side_effects = ssa_to_acir_program(src_no_side_effects);
assert_ne!(program_side_effects, program_no_side_effects);
}
Loading