diff --git a/compiler/noirc_evaluator/src/acir/arrays.rs b/compiler/noirc_evaluator/src/acir/arrays.rs index 50a06b1c2a9..1cbe6357ef2 100644 --- a/compiler/noirc_evaluator/src/acir/arrays.rs +++ b/compiler/noirc_evaluator/src/acir/arrays.rs @@ -235,19 +235,14 @@ impl Context<'_> { } let array_typ = dfg.type_of_value(array); - let offset = self.compute_offset(instruction, dfg, &array_typ); - let (new_index, new_value) = self.convert_array_operation_inputs( - array, - dfg, - index, - store_value, - offset.unwrap_or_default(), - )?; + let offset = self.compute_offset(instruction, dfg, &array_typ, store_value); + let (new_index, new_value) = + self.convert_array_operation_inputs(array, dfg, index, store_value, offset)?; if let Some(new_value) = new_value { self.array_set(instruction, new_index, new_value, dfg, mutable)?; } else { - self.array_get(instruction, array, new_index, dfg, offset.is_none())?; + self.array_get(instruction, array, new_index, dfg)?; } Ok(()) @@ -388,21 +383,27 @@ impl Context<'_> { instruction: InstructionId, dfg: &DataFlowGraph, array_typ: &Type, - ) -> Option { - let is_simple_array = dfg.instruction_results(instruction).len() == 1 - && (array_has_constant_element_size(array_typ) == Some(1)); - if is_simple_array { - let result_type = dfg.type_of_value(dfg.instruction_results(instruction)[0]); - match array_typ { - Type::Array(item_type, _) | Type::Vector(item_type) => item_type - .iter() - .enumerate() - .find_map(|(index, typ)| (result_type == *typ).then_some(index)), - _ => None, - } + store_value: Option, + ) -> usize { + let value_at_index = if let Some(store_value) = store_value { + store_value } else { - None + let [result] = dfg.instruction_result(instruction); + result + }; + let value_type = dfg.type_of_value(value_at_index); + match array_typ { + Type::Array(item_type, _) | Type::Vector(item_type) => { + for (index, typ) in item_type.iter().enumerate() { + if &value_type == typ { + return index; + } + } + } + _ => (), } + + unreachable!("ICE: should always be able to compute offset for array operation"); } /// We need to properly setup the inputs for array operations in ACIR. @@ -584,13 +585,11 @@ impl Context<'_> { array: ValueId, var_index: AcirVar, dfg: &DataFlowGraph, - index_side_effect: bool, ) -> Result<(), RuntimeError> { let block_id = self.ensure_array_is_initialized(array, dfg)?; let [result] = dfg.instruction_result(instruction); let res_typ = dfg.type_of_value(result); let value = self.load_array_value(array, block_id, var_index, &res_typ, dfg)?; - let value = self.apply_index_side_effects(array, value, index_side_effect, dfg)?; self.define_result(dfg, instruction, value); Ok(()) } @@ -645,51 +644,6 @@ impl Context<'_> { } } - /// Applies predication logic on the result in case the read under a false predicate - /// returns a value with a larger type that may later trigger an overflow. - /// Ensures values read under false predicate are zeroed out if types don’t align. - /// This is done recursively for nested arrays. - fn apply_index_side_effects( - &mut self, - array: ValueId, - mut value: AcirValue, - mut index_side_effect: bool, - dfg: &DataFlowGraph, - ) -> Result { - match &value { - AcirValue::Var(acir_var, typ) => { - // If we read under a false predicate, we will read element 0, which has `numeric_type`. - // The variable we expect to read is of `typ`. We check whether reading 0 is compatible with `typ`. - let array_typ = dfg.type_of_value(array); - if let Type::Numeric(numeric_type) = array_typ.first() - && numeric_type.bit_size::() <= typ.bit_size::() - { - // first element is compatible - index_side_effect = false; - } - - if index_side_effect { - value = AcirValue::Var( - self.acir_context - .mul_var(*acir_var, self.current_side_effects_enabled_var)?, - *typ, - ); - } - } - AcirValue::Array(vector) => { - let new_values = try_vecmap(vector.iter(), |val| { - self.apply_index_side_effects(array, val.clone(), index_side_effect, dfg) - })?; - value = AcirValue::Array(im::Vector::from(new_values)); - } - AcirValue::DynamicArray(_) => { - unreachable!("ICE: Nested dynamic arrays are not supported") - } - } - - Ok(value) - } - pub(super) fn array_get_value( &mut self, ssa_type: &Type, diff --git a/compiler/noirc_evaluator/src/ssa/ir/types.rs b/compiler/noirc_evaluator/src/ssa/ir/types.rs index a637a814e0b..2909a7197d7 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/types.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/types.rs @@ -314,14 +314,6 @@ impl Type { } } - pub(crate) fn first(&self) -> Type { - match self { - Type::Numeric(_) | Type::Function => self.clone(), - Type::Reference(typ) => typ.first(), - Type::Vector(element_types) | Type::Array(element_types, _) => element_types[0].first(), - } - } - /// True if this is a reference type or if it is a composite type which contains a reference. pub(crate) fn contains_reference(&self) -> bool { match self {