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
14 changes: 9 additions & 5 deletions compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,11 +1165,15 @@ impl<'a> Context<'a> {
let index_var = self.convert_numeric_value(index, dfg)?;
let index_var = self.get_flattened_index(&array_typ, array_id, index_var, dfg)?;

// predicate_index = index*predicate + (1-predicate)*offset
let offset = self.acir_context.add_constant(offset);
let sub = self.acir_context.sub_var(index_var, offset)?;
let pred = self.acir_context.mul_var(sub, self.current_side_effects_enabled_var)?;
let predicate_index = self.acir_context.add_var(pred, offset)?;
let predicate_index = if dfg.is_safe_index(index, array_id) {
index_var
} else {
// index*predicate + (1-predicate)*offset
let offset = self.acir_context.add_constant(offset);
let sub = self.acir_context.sub_var(index_var, offset)?;
let pred = self.acir_context.mul_var(sub, self.current_side_effects_enabled_var)?;
self.acir_context.add_var(pred, offset)?
};

let new_value = if let Some(store) = store_value {
let store_value = self.convert_value(store, dfg);
Expand Down
8 changes: 8 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ impl DataFlowGraph {
}
}

/// A constant index less than the array length is safe
pub(crate) fn is_safe_index(&self, index: ValueId, array: ValueId) -> bool {
#[allow(clippy::match_like_matches_macro)]
match (self.type_of_value(array), self.get_numeric_constant(index)) {
(Type::Array(_, len), Some(index)) if index.to_u128() < (len as u128) => true,
_ => false,
}
}
/// Sets the terminator instruction for the given basic block
pub(crate) fn set_block_terminator(
&mut self,
Expand Down
8 changes: 2 additions & 6 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,9 @@ impl Instruction {
true
}

// `ArrayGet`s which read from "known good" indices from an array don't need a predicate.
Instruction::ArrayGet { array, index } => {
#[allow(clippy::match_like_matches_macro)]
match (dfg.type_of_value(*array), dfg.get_numeric_constant(*index)) {
(Type::Array(_, len), Some(index)) if index.to_u128() < (len as u128) => false,
_ => true,
}
// `ArrayGet`s which read from "known good" indices from an array should not need a predicate.
!dfg.is_safe_index(*index, *array)
}

Instruction::EnableSideEffects { .. } | Instruction::ArraySet { .. } => true,
Expand Down
2 changes: 2 additions & 0 deletions test_programs/execution_success/sha256/Prover.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ result = [
0x73,
0x2b,
]
input = [0, 0]
toggle = false
7 changes: 6 additions & 1 deletion test_programs/execution_success/sha256/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
// Not yet here: For R1CS, it is more about manipulating arithmetic gates to get performance
// This can be done in ACIR!

fn main(x: Field, result: [u8; 32]) {
fn main(x: Field, result: [u8; 32], input: [u8; 2], toggle: bool) {
// We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field
// The padding is taken care of by the program
// docs:start:sha256_var
let digest = std::hash::sha256_var([x as u8], 1);
// docs:end:sha256_var
assert(digest == result);

// variable size
let size: Field = 1 + toggle as Field;
let var_sha = std::hash::sha256_var(input, size as u64);
assert(var_sha == std::hash::sha256_var(input, 1));
}