From e993da1b01aa98deed2af7b5cba2da216fb036a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Tue, 17 Sep 2024 20:51:50 +0200 Subject: [PATCH] fix: Update databus in flattening (#6063) # Description ## Problem\* Resolves #5705 ## Summary\* We were using an inserter in flattening but forgot to update the databus ## 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\* - [ ] I have tested the changes locally. - [ ] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../src/ssa/ir/function_inserter.rs | 8 ++++ .../src/ssa/opt/flatten_cfg.rs | 1 + .../noirc_evaluator/src/ssa/opt/mem2reg.rs | 3 +- .../databus_mapping_regression/Nargo.toml | 7 ++++ .../databus_mapping_regression/src/main.nr | 42 +++++++++++++++++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 test_programs/compile_success_no_bug/databus_mapping_regression/Nargo.toml create mode 100644 test_programs/compile_success_no_bug/databus_mapping_regression/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs b/compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs index 06325b31dd0..9221a925aa8 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/function_inserter.rs @@ -102,6 +102,14 @@ impl<'f> FunctionInserter<'f> { self.function.dfg[block].set_terminator(terminator); } + /// Maps the data bus in place, replacing any ValueId in the data bus with the + /// resolved version of that value id from this FunctionInserter's internal value mapping. + pub(crate) fn map_data_bus_in_place(&mut self) { + let data_bus = self.function.dfg.data_bus.clone(); + let data_bus = data_bus.map_values(|value| self.resolve(value)); + self.function.dfg.data_bus = data_bus; + } + /// Push a new instruction to the given block and return its new InstructionId. /// If the instruction was simplified out of the program, None is returned. pub(crate) fn push_instruction( diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 613a5df4063..467514114e4 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -289,6 +289,7 @@ impl<'f> Context<'f> { } } } + self.inserter.map_data_bus_in_place(); } /// Returns the updated condition so that diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 13e1e181dec..11bd9debd35 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -436,8 +436,7 @@ impl<'f> PerFunctionContext<'f> { } fn update_data_bus(&mut self) { - let databus = self.inserter.function.dfg.data_bus.clone(); - self.inserter.function.dfg.data_bus = databus.map_values(|t| self.inserter.resolve(t)); + self.inserter.map_data_bus_in_place(); } fn handle_terminator(&mut self, block: BasicBlockId, references: &mut Block) { diff --git a/test_programs/compile_success_no_bug/databus_mapping_regression/Nargo.toml b/test_programs/compile_success_no_bug/databus_mapping_regression/Nargo.toml new file mode 100644 index 00000000000..7ce13902c32 --- /dev/null +++ b/test_programs/compile_success_no_bug/databus_mapping_regression/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "databus_mapping_regression" +type = "bin" +authors = [""] +compiler_version = ">=0.31.0" + +[dependencies] diff --git a/test_programs/compile_success_no_bug/databus_mapping_regression/src/main.nr b/test_programs/compile_success_no_bug/databus_mapping_regression/src/main.nr new file mode 100644 index 00000000000..a3aae2911bb --- /dev/null +++ b/test_programs/compile_success_no_bug/databus_mapping_regression/src/main.nr @@ -0,0 +1,42 @@ +trait Empty { + fn empty() -> Self; +} + +impl Empty for Field { + fn empty() -> Self { + 0 + } +} + +pub fn is_empty(item: T) -> bool where T: Empty + Eq { + item.eq(T::empty()) +} + +pub fn array_to_bounded_vec(array: [T; N]) -> BoundedVec where T: Empty + Eq { + let mut len = 0; + for elem in array { + if !is_empty(elem) { + len += 1; + } + } + + BoundedVec { storage: array, len } +} + +global TX_SIZE = 5; +global APP_CALL_SIZE = 2; + +fn main( + a: call_data(0) [Field; TX_SIZE], + b: call_data(1) [Field; APP_CALL_SIZE] +) -> return_data [Field; TX_SIZE] { + let mut a_as_bounded_vec = array_to_bounded_vec(a); + + for i in 0..APP_CALL_SIZE { + let value = b[i]; + if value != 0 { + a_as_bounded_vec.push(value); + } + } + a_as_bounded_vec.storage +}