Skip to content

Commit aea5cc7

Browse files
vezenovmjfecher
andauthored
fix(mem2reg): Remove possibility of underflow (#6107)
# Description ## Problem\* Resolves ICE ran into by @asterite ## Summary\* After #5925 we have a couple counters that both increment and decrement. In theory they are never supposed to underflow. @asterite has discovered a bug with the remaining last stores counter. I would like to implement the remaining last stores removal in a better way that removes the need for this counter to be decremented, but for now I just block if by check we are not decrementing zero. ## Additional Context ## Documentation\* Check one: - [X] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: jfecher <jake@aztecprotocol.com>
1 parent c40eb1f commit aea5cc7

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ impl<'f> PerFunctionContext<'f> {
288288
.filter(|param| self.inserter.function.dfg.value_is_reference(**param))
289289
.collect::<BTreeSet<_>>();
290290

291+
// Must collect here as we are immutably borrowing `self` to fetch the reference parameters
292+
let mut values_to_reduce_counts = Vec::new();
291293
for (allocation, instruction) in &references.last_stores {
292294
if let Some(expression) = references.expressions.get(allocation) {
293295
if let Some(aliases) = references.aliases.get(expression) {
@@ -297,13 +299,15 @@ impl<'f> PerFunctionContext<'f> {
297299
// If `allocation_aliases_parameter` is known to be false
298300
if allocation_aliases_parameter == Some(false) {
299301
self.instructions_to_remove.insert(*instruction);
300-
if let Some(context) = self.load_results.get_mut(allocation) {
301-
context.uses -= 1;
302-
}
302+
values_to_reduce_counts.push(*allocation);
303303
}
304304
}
305305
}
306306
}
307+
308+
for value in values_to_reduce_counts {
309+
self.reduce_load_result_count(value);
310+
}
307311
}
308312

309313
fn increase_load_ref_counts(&mut self, value: ValueId) {
@@ -406,25 +410,17 @@ impl<'f> PerFunctionContext<'f> {
406410
else {
407411
panic!("Should have a store instruction here");
408412
};
409-
if let Some(context) = self.load_results.get_mut(&address) {
410-
context.uses -= 1;
411-
}
412-
if let Some(context) = self.load_results.get_mut(&value) {
413-
context.uses -= 1;
414-
}
413+
self.reduce_load_result_count(address);
414+
self.reduce_load_result_count(value);
415415
}
416416

417417
let known_value = references.get_known_value(value);
418418
if let Some(known_value) = known_value {
419419
let known_value_is_address = known_value == address;
420420
if known_value_is_address {
421421
self.instructions_to_remove.insert(instruction);
422-
if let Some(context) = self.load_results.get_mut(&address) {
423-
context.uses -= 1;
424-
}
425-
if let Some(context) = self.load_results.get_mut(&value) {
426-
context.uses -= 1;
427-
}
422+
self.reduce_load_result_count(address);
423+
self.reduce_load_result_count(value);
428424
} else {
429425
references.last_stores.insert(address, instruction);
430426
}
@@ -617,6 +613,12 @@ impl<'f> PerFunctionContext<'f> {
617613
}
618614
}
619615

616+
fn reduce_load_result_count(&mut self, value: ValueId) {
617+
if let Some(context) = self.load_results.get_mut(&value) {
618+
context.uses = context.uses.saturating_sub(1);
619+
}
620+
}
621+
620622
fn recursively_add_values(&self, value: ValueId, set: &mut HashSet<ValueId>) {
621623
set.insert(value);
622624
if let Some((elements, _)) = self.inserter.function.dfg.get_array_constant(value) {
@@ -741,7 +743,7 @@ impl<'f> PerFunctionContext<'f> {
741743
if all_loads_removed && !store_alias_used {
742744
self.instructions_to_remove.insert(*store_instruction);
743745
if let Some((_, counter)) = remaining_last_stores.get_mut(store_address) {
744-
*counter -= 1;
746+
*counter = counter.saturating_sub(1);
745747
}
746748
} else if let Some((_, counter)) = remaining_last_stores.get_mut(store_address) {
747749
*counter += 1;

0 commit comments

Comments
 (0)