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
9 changes: 7 additions & 2 deletions compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,15 +458,20 @@ impl<'f> PerFunctionContext<'f> {
let result = self.inserter.function.dfg.instruction_results(instruction)[0];
references.remember_dereference(self.inserter.function, address, result);

// If the load is known, replace it with the known value and remove the load
// If the load is known, replace it with the known value and remove the load.
if let Some(value) = references.get_known_value(address) {
let result = self.inserter.function.dfg.instruction_results(instruction)[0];
self.inserter.map_value(result, value);
self.instructions_to_remove.insert(instruction);
} else {
// We don't know the exact value of the address, so we must keep the stores to it.
references.mark_value_used(address, self.inserter.function);

// Remember that this address has been loaded, so stores to it should not be removed.
self.last_loads.insert(address, (instruction, block_id));
// Stores to any of its aliases should also be considered loaded.
references.for_each_alias_of(address, |_, alias| {
self.last_loads.insert(alias, (instruction, block_id));
});
}

// Check whether the block has a repeat load from the same address (w/ no calls or stores in between the loads).
Expand Down
12 changes: 12 additions & 0 deletions compiler/noirc_evaluator/src/ssa/opt/mem2reg/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,21 @@ impl Block {
}
}

/// Forget the last store to an address and all of its aliases, to eliminate them
/// from the candidates for removal at the end.
///
/// Note that this only affects this block: when we merge blocks we clear the
/// last stores anyway, we don't inherit them from predecessors, so if one
/// block stores to an address and a descendant block loads it, this mechanism
/// does not affect the candidacy of the last store in the predecessor block.
fn keep_last_stores_for(&mut self, address: ValueId, function: &Function) {
self.keep_last_store(address, function);
self.for_each_alias_of(address, |t, alias| t.keep_last_store(alias, function));
}

/// Forget the last store to an address, to remove it from the set of instructions
/// which are candidates for removal at the end. Also marks the values in the last
/// store as used, now that we know we want to keep them.
fn keep_last_store(&mut self, address: ValueId, function: &Function) {
if let Some(instruction) = self.last_stores.remove(&address) {
// Whenever we decide we want to keep a store instruction, we also need
Expand All @@ -206,6 +216,8 @@ impl Block {
}
}

/// Mark a value (for example an address we loaded) as used by forgetting the last store instruction,
/// which removes it from the candidates for removal.
pub(super) fn mark_value_used(&mut self, value: ValueId, function: &Function) {
self.keep_last_stores_for(value, function);

Expand Down
6 changes: 6 additions & 0 deletions test_programs/execution_success/regression_9538/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "regression_9538"
type = "bin"
authors = [""]

[dependencies]
3 changes: 3 additions & 0 deletions test_programs/execution_success/regression_9538/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a = true
b = ["one", "two"]
return = "two"
10 changes: 10 additions & 0 deletions test_programs/execution_success/regression_9538/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
unconstrained fn main(a: bool, mut b: (str<3>, str<3>)) -> pub str<3> {
if a {
func_2((if a { (&mut b.1) } else { (&mut b.0) }))
} else {
func_2((if a { (&mut b.1) } else { (&mut b.0) }))
}
}
unconstrained fn func_2(a: &mut str<3>) -> str<3> {
*a
}
1 change: 1 addition & 0 deletions tooling/debugger/ignored-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ reference_counts_slices_inliner_0
references
regression_4709
regression_7323
regression_9538
reference_only_used_as_alias
brillig_rc_regression_6123
array_rc_regression_7842
Expand Down

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

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

Loading
Loading