diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index d8dba499a43..c813bc955dd 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -623,8 +623,8 @@ impl Instruction { } } Instruction::ArrayGet { array, index } => { - if let Some(index) = dfg.get_numeric_constant(*index) { - try_optimize_array_get_from_previous_set(dfg, *array, index) + if let Some(index_value) = dfg.get_numeric_constant(*index) { + try_optimize_array_get_from_previous_set(dfg, *array, index_value, *index) } else { None } @@ -776,8 +776,9 @@ impl Instruction { /// - If the array value is from a previous array-set, we recur. fn try_optimize_array_get_from_previous_set( dfg: &DataFlowGraph, - mut array_id: Id, + mut array_id: ValueId, target_index: FieldElement, + index_id: ValueId, ) -> SimplifyResult { let mut elements = None; @@ -805,6 +806,12 @@ fn try_optimize_array_get_from_previous_set( elements = Some(array.clone()); break; } + // None of the past array sets changed this index so redirect this array get + // to the original param. This lets it potentially be de-duplicated later. + Value::Param { .. } => { + let new_get = Instruction::ArrayGet { array: array_id, index: index_id }; + return SimplifyResult::SimplifiedToInstruction(new_get); + } _ => return SimplifyResult::None, } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs index 3b86ded4a87..d16b0a6f431 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs @@ -828,12 +828,8 @@ mod test { // enable_side_effects v0 // v3 = array_get v2, index Field 0 // v4 = array_set v2, index Field 1, value: Field 2 - // v5 = array_get v4, index Field 0 - // constrain_eq v3, v5 // enable_side_effects v1 // v7 = array_set v2, index Field 1, value: Field 2 - // v8 = array_get v7, index Field 0 - // constrain_eq v3, v8 // enable_side_effects v0 // } let ssa = ssa.fold_constants_using_constraints(); @@ -841,7 +837,7 @@ mod test { let main = ssa.main(); let instructions = main.dfg[main.entry_block()].instructions(); - assert_eq!(instructions.len(), 10); + assert_eq!(instructions.len(), 6); } // This test currently fails. It being fixed will address the issue https://github.com/noir-lang/noir/issues/5756