Skip to content

Commit

Permalink
feat: add support for assert in brillig (#1603)
Browse files Browse the repository at this point in the history
* remove mac runner

* chore: generate brillig opcode for simple identity unconstrained function (#1536)

* feat(brillig): added arithmetic operations on brillig (#1565)

Co-authored-by: kevaundray <[email protected]>

* make ranges be polymorphic integers

* chore(brillig): Clean up handling of Binary operations (#1571)

* chore(ssa refactor): Rename Brillig example (#1563)

* chore(brillig): added tests for all field binary operations (#1586)

* chore(brillig): added tests for brillig integer operations (#1590)

* feat: process blocks and jumps when compiling brillig (#1591)

* process jumps between blocks

* fix jumps

* add doc comments

* cargo fmt

* code refactor

* update code comment

---------

Co-authored-by: kevaundray <[email protected]>

* feat: process blocks and jumps when compiling brillig (#1591)

* process jumps between blocks

* fix jumps

* add doc comments

* cargo fmt

* code refactor

* update code comment

---------

Co-authored-by: kevaundray <[email protected]>

* feat(brillig): parsing oracles/foreign calls (#1596)

* feat(brillig): start of oracles/foreign calls

* fix: broken tests

* Update execute.rs

* support assert in brillig

* self.data -> self.vars

* Avoid not in the test

* chore(brillig): Add handling of the not instruction (#1609)

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

* feat(brillig): loops (#1610)

* make ranges be polymorphic integers

* feat: brillig loop support

* fix: fixed brillig returns and stop

* fix: do not apply constants folding to brillig fns

* chore: update acvm pointer, cleanup

* style: newline on cargo toml

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

* better debug information for unsupported instruction

* remove edge case for optimizations

* clippy fix

* patch infinite loop

---------

Co-authored-by: kevaundray <[email protected]>
Co-authored-by: jfecher <[email protected]>

* chore: resolve immutable array merge differences (#1617)

* chore(ssa refactor): Switch to immutable arrays (#1578)

* Represent SSA arrays with im::Vector

* Get tests passing

* Implement assign with immutable arrays

* Add constant folding pass

* Update comments

* Clippy

* Update comment

* Update type of array

* Update crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs

Co-authored-by: Tom French <[email protected]>

* Undo formatting changes in instruction.rs

* Massive acir_gen update

* Refactor acir array operations into a shared function

* Appease clippy

* Update to_radix and to_bits in acir_gen to return arrays

* Disable assert

* Fix convert_type for arrays

* Include AcirType in AcirValue::Var variant

* Fix black box functions

* Appease clippy

* Fix simple_radix

* Add doc comments

---------

Co-authored-by: Tom French <[email protected]>

* feat: Make for-loop range be a polymorphic integer instead of just Field in unconstrained functions (#1583)

* make ranges be polymorphic integers

* make behavior consistent

* remove closure

* change index_type

* Update crates/noirc_frontend/src/hir/type_check/expr.rs

---------

Co-authored-by: jfecher <[email protected]>

* chore(ssa refactor): fix brillig post master merge

* chore(ssa refactor): accidental merge undelete

---------

Co-authored-by: jfecher <[email protected]>
Co-authored-by: Tom French <[email protected]>
Co-authored-by: kevaundray <[email protected]>

* chore(ssa refactor): Add more documentation for truncation  (#1607)

* add more documentation

* small change

* Update crates/noirc_evaluator/src/ssa_refactor/acir_gen/acir_ir/generated_acir.rs

* Update .github/workflows/test.yml

* Update .github/workflows/test.yml

* Remove optimisation for handling assert

* add the assert jump to the list of jumps to fix

* add doc comment

---------

Co-authored-by: kevaundray <[email protected]>
Co-authored-by: Álvaro Rodríguez <[email protected]>
Co-authored-by: ludamad <[email protected]>
Co-authored-by: jfecher <[email protected]>
Co-authored-by: joss-aztec <[email protected]>
Co-authored-by: Tom French <[email protected]>
  • Loading branch information
7 people authored Jun 9, 2023
1 parent 6bd5a8d commit 03d5040
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 9 deletions.
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 @@
x = "1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Tests a very simple program.
//
// The features being tested is using assert on brillig
fn main(x: Field) {
assert(1 == conditional(x as bool));
}

unconstrained fn conditional(x : bool) -> Field {
assert(x);
1
}
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 @@
x = "0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Tests a very simple program.
//
// The features being tested is using assert on brillig
fn main(x: Field) {
assert(1 == conditional(x as bool));
}

unconstrained fn conditional(x : bool) -> Field {
assert(x);
1
}
2 changes: 1 addition & 1 deletion crates/nargo_cli/tests/test_data_ssa_refactor/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ exclude = []


# List of tests (as their directory name) expecting to fail: if the test pass, we report an error.
fail = [""]
fail = ["brillig_assert_fail"]
35 changes: 30 additions & 5 deletions crates/noirc_evaluator/src/brillig/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,32 @@ pub(crate) struct BrilligArtifact {
pub(crate) byte_code: Vec<BrilligOpcode>,
/// The set of jumps that need to have their locations
/// resolved.
unresolved_jumps: Vec<(JumpLabel, BasicBlockId)>,
unresolved_jumps: Vec<(JumpLabel, UnresolvedJumpLocation)>,
/// A map of the basic blocks to their positions
/// in the bytecode.
blocks: HashMap<BasicBlockId, BlockLabel>,
}

/// When constructing the bytecode, there may be instructions
/// which require one to jump to a specific `Block`
/// or a position relative to the current instruction.
///
/// The position of a `Block` cannot always be known
/// at this point in time, so Jumps are unresolved
/// until all blocks have been processed in the `Block`
/// variant of this enum.
///
/// Sometimes the relative position of an Jump
/// may be known, from the Jump label, but since
/// the absolute position of a Jump label is not known until
/// after we have linked the bytecode to other functions.
/// We add relative jumps into the `Relative` variant of this enum.
#[derive(Debug, Clone, Copy)]
pub(crate) enum UnresolvedJumpLocation {
Block(BasicBlockId),
Relative(i32),
}

impl BrilligArtifact {
/// Link some compiled brillig bytecode with its referenced artifacts.
pub(crate) fn link(&mut self, obj: &BrilligArtifact) -> Vec<BrilligOpcode> {
Expand All @@ -46,7 +66,7 @@ impl BrilligArtifact {
}

/// Adds a unresolved jump to be fixed at the end of bytecode processing.
pub(crate) fn add_unresolved_jump(&mut self, destination: BasicBlockId) {
pub(crate) fn add_unresolved_jump(&mut self, destination: UnresolvedJumpLocation) {
self.unresolved_jumps.push((self.code_len(), destination));
}

Expand All @@ -65,10 +85,15 @@ impl BrilligArtifact {
///
/// Note: This should only be called once all blocks are processed.
fn resolve_jumps(&mut self) {
for (jump_label, block) in &self.unresolved_jumps {
for (jump_label, unresolved_location) in &self.unresolved_jumps {
let jump_instruction = self.byte_code[*jump_label].clone();

let actual_block_location = self.blocks[block];
let actual_block_location = match unresolved_location {
UnresolvedJumpLocation::Block(b) => self.blocks[b],
UnresolvedJumpLocation::Relative(location) => {
(location + *jump_label as i32) as usize
}
};

match jump_instruction {
BrilligOpcode::Jump { location } => {
Expand All @@ -84,7 +109,7 @@ impl BrilligArtifact {
BrilligOpcode::JumpIfNot { condition, location: actual_block_location };
}
BrilligOpcode::JumpIf { condition, location } => {
assert_eq!(location, 0,"location is not zero, which means that the jump label does not need resolving");
assert_eq!(location, 0, "location is not zero, which means that the jump label does not need resolving");

self.byte_code[*jump_label] =
BrilligOpcode::JumpIf { condition, location: actual_block_location };
Expand Down
13 changes: 10 additions & 3 deletions crates/noirc_evaluator/src/brillig/brillig_gen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{
artifact::BrilligArtifact,
artifact::{BrilligArtifact, UnresolvedJumpLocation},
binary::{type_of_binary_operation, BrilligBinaryOp},
memory::BrilligMemory,
};
Expand Down Expand Up @@ -103,13 +103,13 @@ impl BrilligGen {

/// Adds a unresolved `Jump` instruction to the bytecode.
fn jump(&mut self, target: BasicBlockId) {
self.obj.add_unresolved_jump(target);
self.obj.add_unresolved_jump(UnresolvedJumpLocation::Block(target));
self.push_code(BrilligOpcode::Jump { location: 0 });
}

/// Adds a unresolved `JumpIf` instruction to the bytecode.
fn jump_if(&mut self, condition: RegisterIndex, target: BasicBlockId) {
self.obj.add_unresolved_jump(target);
self.obj.add_unresolved_jump(UnresolvedJumpLocation::Block(target));
self.push_code(BrilligOpcode::JumpIf { condition, location: 0 });
}

Expand Down Expand Up @@ -162,6 +162,13 @@ impl BrilligGen {
let result_register = self.get_or_create_register(result_ids[0]);
self.convert_ssa_binary(binary, dfg, result_register);
}
Instruction::Constrain(value) => {
let condition = self.convert_ssa_value(*value, dfg);
// jump to the relative location after the trap
self.obj.add_unresolved_jump(UnresolvedJumpLocation::Relative(2));
self.push_code(BrilligOpcode::JumpIf { condition, location: 0 });
self.push_code(BrilligOpcode::Trap);
}
Instruction::Allocate => {
let pointer_register =
self.get_or_create_register(dfg.instruction_results(instruction_id)[0]);
Expand Down

0 comments on commit 03d5040

Please sign in to comment.