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
44 changes: 43 additions & 1 deletion compiler/noirc_evaluator/src/ssa/opt/array_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
impl Function {
pub(crate) fn array_set_optimization(&mut self) {
if matches!(self.runtime(), RuntimeType::Brillig(_)) {
// Brillig is supposed to use refcounting to decide whether to mutate an array;

Check warning on line 75 in compiler/noirc_evaluator/src/ssa/opt/array_set.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (refcounting)
// array mutation was only meant for ACIR. We could use it with Brillig as well,
// but then some of the optimizations that we can do in ACIR around shared
// references have to be skipped, which makes it more cumbersome.
Expand Down Expand Up @@ -193,6 +193,15 @@
self.arrays_from_load.insert(result, is_reference_param);
}
}
Instruction::MakeArray { elements, .. } => {
for element in elements {
if let Some(existing) =
self.array_to_last_use.insert(*element, *instruction_id)
{
self.instructions_that_can_be_made_mutable.remove(&existing);
}
}
}
_ => (),
}
}
Expand All @@ -213,7 +222,10 @@

#[cfg(test)]
mod tests {
use crate::ssa::{Ssa, opt::assert_normalized_ssa_equals};
use crate::{
assert_ssa_snapshot,
ssa::{Ssa, opt::assert_normalized_ssa_equals},
};

#[test]
fn array_set_in_loop_with_conditional_clone() {
Expand Down Expand Up @@ -258,4 +270,34 @@
let ssa = ssa.array_set_optimization();
assert_normalized_ssa_equals(ssa, src);
}

#[test]
fn does_not_mutate_array_used_in_make_array() {
// Regression test for https://github.com/noir-lang/noir/issues/8563
// Previously `v2` would be marked as mutable in the first array_set, which results in `v5` being invalid.
let src = "
acir(inline) fn main f0 {
b0():
v2 = make_array [Field 0] : [Field; 1]
v3 = array_set v2, index u32 0, value Field 2
v4 = make_array [v2, v2] : [[Field; 1]; 2]
v5 = array_set v4, index u32 0, value v2
return v5
}
";
let ssa = Ssa::from_str(src).unwrap();

// We expect the same result as above
let ssa = ssa.array_set_optimization();
assert_ssa_snapshot!(ssa, @r"
acir(inline) fn main f0 {
b0():
v1 = make_array [Field 0] : [Field; 1]
v4 = array_set v1, index u32 0, value Field 2
v5 = make_array [v1, v1] : [[Field; 1]; 2]
v6 = array_set mut v5, index u32 0, value v1
return v6
}
");
}
}
Loading