Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ssa refactor): allow simplified call inserts & fix const radix arg handling #1774

Merged
merged 5 commits into from
Jun 21, 2023
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "2040124"
a = "0x2000000000000000000000000000000000000000000000000000000000000000"
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use dep::std;

fn main(x : Field, a: Field) {
let y: Field = 2040124;
let be_byte_array = y.to_be_bytes(31);
let le_byte_array = x.to_le_bytes(31);

assert(le_byte_array[0] == 60);
assert(le_byte_array[0] == be_byte_array[30]);
assert(le_byte_array[1] == be_byte_array[29]);
assert(le_byte_array[2] == be_byte_array[28]);

let z = 0 - 1;
let p_bytes = std::field::modulus_le_bytes();
let z_bytes = z.to_le_bytes(32);
assert(p_bytes[10] == z_bytes[10]);
assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8);

let p_bits = std::field::modulus_le_bits();
let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32);
assert(z_bits[0] == 0);
assert(p_bits[100] == z_bits[100]);

a.to_le_bits(std::field::modulus_num_bits() as u32);
}
13 changes: 5 additions & 8 deletions crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, rc::Rc};
use std::{borrow::Cow, collections::HashMap, rc::Rc};

use crate::ssa_refactor::ir::instruction::SimplifyResult;

Expand Down Expand Up @@ -414,14 +414,11 @@ impl<'dfg> InsertInstructionResult<'dfg> {
}

/// Return all the results contained in the internal results array.
/// This is used for instructions returning multiple results that were
/// not simplified - like function calls.
pub(crate) fn results(&self) -> &'dfg [ValueId] {
/// This is used for instructions returning multiple results like function calls.
pub(crate) fn results(&self) -> Cow<'dfg, [ValueId]> {
match self {
InsertInstructionResult::Results(results) => results,
InsertInstructionResult::SimplifiedTo(_) => {
panic!("InsertInstructionResult::results called on a simplified instruction")
}
InsertInstructionResult::Results(results) => Cow::Borrowed(results),
InsertInstructionResult::SimplifiedTo(result) => Cow::Owned(vec![*result]),
InsertInstructionResult::InstructionRemoved => {
panic!("InsertInstructionResult::results called on a removed instruction")
}
Expand Down
2 changes: 1 addition & 1 deletion crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ fn simplify_call(func: ValueId, arguments: &[ValueId], dfg: &mut DataFlowGraph)
Intrinsic::ToRadix(endian) => {
let field = constant_args[0];
let radix = constant_args[1].to_u128() as u32;
let limb_count = constant_args[1].to_u128() as u32;
let limb_count = constant_args[2].to_u128() as u32;
SimplifiedTo(constant_to_radix(endian, field, radix, limb_count, dfg))
}
Intrinsic::BlackBox(_) | Intrinsic::Println | Intrinsic::Sort => None,
Expand Down
47 changes: 45 additions & 2 deletions crates/noirc_evaluator/src/ssa_refactor/ssa_builder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::rc::Rc;
use std::{borrow::Cow, rc::Rc};

use acvm::FieldElement;

Expand Down Expand Up @@ -236,7 +236,7 @@ impl FunctionBuilder {
func: ValueId,
arguments: Vec<ValueId>,
result_types: Vec<Type>,
) -> &[ValueId] {
) -> Cow<[ValueId]> {
self.insert_instruction(Instruction::Call { func, arguments }, Some(result_types)).results()
}

Expand Down Expand Up @@ -348,3 +348,46 @@ impl std::ops::Index<BasicBlockId> for FunctionBuilder {
&self.current_function.dfg[id]
}
}

#[cfg(test)]
mod tests {
use std::rc::Rc;

use acvm::FieldElement;

use crate::ssa_refactor::ir::{
function::RuntimeType,
instruction::{Endian, Intrinsic},
map::Id,
types::Type,
value::Value,
};

use super::FunctionBuilder;

#[test]
fn insert_constant_call() {
// `bits` should be an array of constants [1, 1, 1, 0...]:
// let x = 7;
// let bits = x.to_le_bits(8);
let func_id = Id::test_new(0);
let mut builder = FunctionBuilder::new("func".into(), func_id, RuntimeType::Acir);
let one = builder.numeric_constant(FieldElement::one(), Type::bool());
let zero = builder.numeric_constant(FieldElement::zero(), Type::bool());

let to_bits_id = builder.import_intrinsic_id(Intrinsic::ToBits(Endian::Little));
let input = builder.numeric_constant(FieldElement::from(7_u128), Type::field());
let length = builder.numeric_constant(FieldElement::from(8_u128), Type::field());
let result_types = vec![Type::Array(Rc::new(vec![Type::bool()]), 8)];
let call_result = builder.insert_call(to_bits_id, vec![input, length], result_types)[0];

let array = match &builder.current_function.dfg[call_result] {
Value::Array { array, .. } => array,
_ => panic!(),
};
assert_eq!(array[0], one);
assert_eq!(array[1], one);
assert_eq!(array[2], one);
assert_eq!(array[3], zero);
}
}