Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions compiler/noirc_evaluator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ similar-asserts.workspace = true
tracing-test = "0.2.5"
num-traits.workspace = true
test-case.workspace = true
function_name = "0.3.0"
noirc_frontend = { workspace = true, features = ["test_utils"] }

[features]
bn254 = ["noirc_frontend/bn254"]
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub(crate) mod context;
mod program;
mod tests;
mod value;

use acvm::AcirField;
Expand Down Expand Up @@ -513,7 +514,7 @@
fn codegen_cast(&mut self, cast: &ast::Cast) -> Result<Values, RuntimeError> {
let lhs = self.codegen_non_tuple_expression(&cast.lhs)?;
let typ = Self::convert_non_tuple_type(&cast.r#type).unwrap_numeric();

Check warning on line 517 in compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (brif)
Ok(self.insert_safe_cast(lhs, typ, cast.location).into())
}

Expand Down Expand Up @@ -657,7 +658,7 @@

// Codegen the body
self.builder.switch_to_block(while_body);
self.codegen_expression(&while_.body)?;

Check warning on line 661 in compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (brif)
self.builder.terminate_with_jmp(while_entry, vec![]);

// Finish by switching to the end of the while
Expand All @@ -672,7 +673,7 @@
///
/// ```text
/// v0 = ... codegen cond ...
/// brif v0, then: then_block, else: else_block

Check warning on line 676 in compiler/noirc_evaluator/src/ssa/ssa_gen/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (brif)
/// then_block():
/// v1 = ... codegen a ...
/// br end_if(v1)
Expand Down
109 changes: 109 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#![cfg(test)]

use crate::{errors::RuntimeError, ssa::opt::assert_normalized_ssa_equals};

use super::{Ssa, generate_ssa};

use function_name::named;

use noirc_frontend::function_path;
use noirc_frontend::test_utils::{Expect, get_monomorphized};

fn get_initial_ssa(src: &str, test_path: &str) -> Result<Ssa, RuntimeError> {
let program = match get_monomorphized(src, test_path, Expect::Success) {
Ok(program) => program,
Err(errors) => {
panic!(
"Expected program to have no errors before SSA generation, but found: {errors:?}"
)
}
};

generate_ssa(program)
}

#[named]
#[test]
fn assert() {
let assert_src = "
fn main(input: u32) {
assert(input == 5);
}
";
let assert_ssa = get_initial_ssa(assert_src, function_path!()).unwrap();

let expected = "
acir(inline) fn main f0 {
b0(v0: u32):
v2 = eq v0, u32 5
constrain v0 == u32 5
return
}
";
assert_normalized_ssa_equals(assert_ssa, expected);
}

#[named]
#[test]
fn assert_eq() {
let assert_eq_src = "
fn main(input: u32) {
assert_eq(input, 5);
}
";

let assert_eq_ssa = get_initial_ssa(assert_eq_src, function_path!()).unwrap();

let expected = "
acir(inline) fn main f0 {
b0(v0: u32):
v2 = eq v0, u32 5
constrain v0 == u32 5
return
}
";
// The SSA from assert_eq should match that from a regular assert checking for equality
// The expected SSA above should match that in the `assert()` test
assert_normalized_ssa_equals(assert_eq_ssa, expected);
}

#[named]
#[test]
fn basic_loop() {
let src = "
fn main(sum_to_check: u32) {
let mut sum = 0;
for i in 0..4 {
sum = sum + i;
}
assert(sum_to_check == sum);
}
";

let ssa = get_initial_ssa(src, function_path!()).unwrap();

let expected = "
acir(inline) fn main f0 {
b0(v0: u32):
v2 = allocate -> &mut u32
store u32 0 at v2
jmp b1(u32 0)
b1(v4: u32):
v5 = lt v4, u32 4
jmpif v5 then: b2, else: b3
b2():
v6 = load v2 -> u32
v7 = add v6, v4
store v7 at v2
v9 = unchecked_add v4, u32 1
jmp b1(v9)
b3():
v10 = load v2 -> u32
v11 = eq v0, v10
constrain v0 == v10
return
}
";

assert_normalized_ssa_equals(ssa, expected);
}
1 change: 1 addition & 0 deletions compiler/noirc_frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ proptest-derive.workspace = true
[features]
bn254 = []
bls12_381 = []
test_utils = []
nextest = []
2 changes: 2 additions & 0 deletions compiler/noirc_frontend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ pub use hir_def::types::*;

// Unit tests that involve all modules
pub mod tests;
// Utility functions for easily compiling the frontend for tests in other crates
pub mod test_utils;
26 changes: 3 additions & 23 deletions compiler/noirc_frontend/src/monomorphization/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,10 @@
use crate::{
check_monomorphization_error_using_features,
elaborator::UnstableFeature,
tests::{Expect, get_program},
test_utils::{Expect, get_monomorphized},
};

use super::{ast::Program, errors::MonomorphizationError, monomorphize};

pub fn get_monomorphized(
src: &str,
test_path: &str,
expect: Expect,
) -> Result<Program, MonomorphizationError> {
let (_parsed_module, mut context, errors) = get_program(src, test_path, expect);
assert!(
errors.iter().all(|err| !err.is_error()),
"Expected monomorphized program to have no errors before monomorphization, but found: {errors:?}"
);

let main = context
.get_main_function(context.root_crate_id())
.unwrap_or_else(|| panic!("get_monomorphized: test program contains no 'main' function"));

monomorphize(main, &mut context.def_interner, false)
}

fn check_rewrite(src: &str, expected: &str, test_path: &str) {
pub(crate) fn check_rewrite(src: &str, expected: &str, test_path: &str) {
let program = get_monomorphized(src, test_path, Expect::Success).unwrap();
assert!(format!("{}", program) == expected);
}
Expand All @@ -34,7 +14,7 @@ fn check_rewrite(src: &str, expected: &str, test_path: &str) {
#[macro_export]
macro_rules! get_monomorphized {
($src:expr, $expect:expr) => {
$crate::monomorphization::tests::get_monomorphized($src, $crate::function_path!(), $expect)
$crate::test_utils::get_monomorphized($src, $crate::function_path!(), $expect)
};
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,7 @@ impl NodeInterner {

/// This function is needed when creating a NodeInterner for testing so that calls
/// to `get_operator_trait` do not panic when the stdlib isn't present.
#[cfg(test)]
#[cfg(any(test, feature = "test_utils"))]
pub fn populate_dummy_operator_traits(&mut self) {
let dummy_trait = TraitId(ModuleId::dummy_id());
self.infix_operator_traits.insert(BinaryOpKind::Add, dummy_trait);
Expand Down
Loading
Loading