chore(ACIR): expand signed lt, div and mod in SSA#10036
Conversation
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'ACVM Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: 090ea14 | Previous: 39f193c | Ratio |
|---|---|---|---|
perfectly_parallel_batch_inversion_opcodes |
2785109 ns/iter (± 9534) |
2254940 ns/iter (± 1115) |
1.24 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @TomAFrench
Changes to circuit sizes
🧾 Summary (10% most significant diffs)
Full diff report 👇
|
|
Huh, I didn't expect Brillig regressions as this PR shouldn't modify Brillig at all... on the other and we can see some ACIR improvements, which I expected because for example when doing signed bitshifts we were using signed "less than" but now it's a simpler unsigned comparison that can be done with less ACIR opcodes. I'll check what's going on with Brillig... |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Test Suite Duration'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: c2e0c77 | Previous: 6898710 | Ratio |
|---|---|---|---|
test_report_noir-lang_sha512_ |
16 s |
13 s |
1.23 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @TomAFrench
|
Aaah... I didn't realize this pass ran on brillig too. I'll change it to not run on brillig for the "less than" case. |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Execution Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: 35f471d | Previous: 6898710 | Ratio |
|---|---|---|---|
rollup-block-root-single-tx |
0.003 s |
0.002 s |
1.50 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @TomAFrench
It's good, the circuit size is what matters at the end. |
Just to note that the new SSA mapping has 2 |
|
One more thing: for the Noir code in the very beginning of this issue, the previous ACIR was: Now it's: Note that we previously used 512 and now we use 256. These values are used to add the two signed values together so they don't underflow. I think the two programs should be equivalent. That said, I don't know why we ended up with 512 before... ah, or maybe when comparing the two values we added 256 twice because a helper ACIR function would also try to avoid underflow... not sure! I just wanted to mention this because I fear this change might have introduced a bug, but on the other hand both ways to do this look good. |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Compilation Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: bddecb5 | Previous: 39f193c | Ratio |
|---|---|---|---|
sha512-100-bytes |
2.107 s |
1.665 s |
1.27 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @TomAFrench
vezenovm
left a comment
There was a problem hiding this comment.
Looks good to me! I generally am in favor of these moves from ACIR gen into our SSA.
In the old |
Co-authored-by: Maxim Vezenov <mvezenov@gmail.com>
Automated pull of nightly from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec. BEGIN_COMMIT_OVERRIDE chore: Remove unnecessary allocation in `expr_with` (noir-lang/noir#10103) chore(ACIR): inline `maybe_eq_predicate` (noir-lang/noir#10095) chore: use `u64` over `Field` in template program (noir-lang/noir#10096) chore: disallow slice arguments to blackbox functions (noir-lang/noir#10090) chore(brillig_vm): Separate fuzzing module (noir-lang/noir#10091) chore: ConstrainNotEqual requires acir predicate (noir-lang/noir#10062) chore: bump version of bb used in tests (noir-lang/noir#10093) chore: wrapping arithmetic tests (noir-lang/noir#9714) chore(brillig_vm): Foreign call module and test re-org (noir-lang/noir#10089) chore: add extra constraint folding pass (noir-lang/noir#9766) chore: refactor brillig_blocks (noir-lang/noir#10088) chore: add regression test for #9986 (noir-lang/noir#10087) chore: Release Noir(1.0.0-beta.14) (noir-lang/noir#9942) fix(tag_attr): keep whitespace tokens when parsing (noir-lang/noir#9981) fix: hoist and then deduplicate (noir-lang/noir#10047) chore: typos and some refactors in `acvm/src/pwg` (noir-lang/noir#10086) chore: add in hack for `public_dispatch` (noir-lang/noir#10084) fix(ssa): Avoid going through `i128` when casting signed to `u128` (noir-lang/noir#10045) chore: avoid zero bits range-checks (noir-lang/noir#10083) chore: bump external pinned commits (noir-lang/noir#10082) fix(stdlib): Only compute the garbage `embedded_curve_result` result if we know we will need it (noir-lang/noir#10077) fix(ssa): Keep defaults for values returned in the databus (noir-lang/noir#10042) chore: remove unused predicate from mem-op solver (noir-lang/noir#10079) chore(ACIR): snapshot tests for each instruction (noir-lang/noir#10071) fix: remove generic length from ECDSA message hash in stdlib (noir-lang/noir#10043) chore: validate that no jumps to function entry block exist (noir-lang/noir#10076) feat(brillig): Centralize memory layout policy and reorganize memory regions (noir-lang/noir#9985) chore(ci): fix permissions about publishing rustdoc (noir-lang/noir#10075) chore(ACVM): use Vec instead of Hash for memory blocks (noir-lang/noir#10072) feat(ssa): `constant_folding` with loop (noir-lang/noir#10019) chore: take truncate into account for bit size (noir-lang/noir#10059) chore: update check for `u128` overflow in `check_u128_mul_overflow` (noir-lang/noir#9998) chore: update check for field overflow in `check_u128_mul_overflow` (noir-lang/noir#9968) chore(ACIR): binary instructions snapshots (noir-lang/noir#10054) chore(acir): SliceRemove refactor (noir-lang/noir#10058) fix(fuzzer): Mark DivisionByZero with different types as equivalent (noir-lang/noir#10066) chore(fuzz): Remove `is_frontend_friendly` from the AST fuzzer (noir-lang/noir#10046) chore: use new ACIR syntax in docs, and some tests (noir-lang/noir#10057) fix(ssa): SSA interpreter to use the 2nd arg in `slice_refcount` (noir-lang/noir#10034) fix(ssa): SSA interpreter to return 0 for `Intrinsic::*RefCount` when constrained (noir-lang/noir#10033) chore(ssa_fuzzer): fix array get/set (noir-lang/noir#10031) fix(acir): Extend slice on dynamic insertion and compilation panic when flattening (noir-lang/noir#10051) chore(ACIR): extract convert_constrain_error helper (noir-lang/noir#10050) chore(ACIR): expand signed lt, div and mod in SSA (noir-lang/noir#10036) chore(ACIR): more consistent syntax and with less noise (noir-lang/noir#10014) chore(acir): Code gen tests for slice intrinsics (noir-lang/noir#10017) feat: parse and display SSA databus (noir-lang/noir#9991) fix(ssa): Handle partially removed `ArrayGet` groups of complex type during OOB checks (noir-lang/noir#10027) chore(acir): binary operations always have the same operand types (noir-lang/noir#10028) feat: Add Module::parent and Module::child_modules (noir-lang/noir#10005) chore: green light for ACVM optimisation (noir-lang/noir#10002) chore: unit test for brillig solver (greenlight ACVM execution) (noir-lang/noir#9967) chore(acir): avoid duplication when invoking brillig stdlib call (noir-lang/noir#10025) chore: Use 8 partitions for rust tests (noir-lang/noir#10026) chore: green light for ACVM execution audit (noir-lang/noir#9982) chore: greenlight for ACVM execution (PWG) (noir-lang/noir#9961) feat: optimize out noop casts on constants (noir-lang/noir#10024) fix(mem2reg): consider call return aliases (noir-lang/noir#10016) chore: bump external pinned commits (noir-lang/noir#10022) fix(parser): enforce left brace after match expression (noir-lang/noir#10018) chore(acir): Intrinsics and slice_ops modules as well as slice_ops doc comments (noir-lang/noir#10012) fix: signed division by -1 can overflow (noir-lang/noir#9976) chore(ci): fix external checks (noir-lang/noir#10009) chore(ci): add provenance attestations to npm packages (noir-lang/noir#10011) chore(ACIR): show all expressions as polynomials (noir-lang/noir#10007) chore: remove unused feature flag (noir-lang/noir#9993) chore(ci): fix docs breaking JS releases (noir-lang/noir#10010) chore(ssa_fuzzer): add external coverage registration (noir-lang/noir#9974) END_COMMIT_OVERRIDE Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Automated pull of nightly from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec. BEGIN_COMMIT_OVERRIDE chore: Remove unnecessary allocation in `expr_with` (noir-lang/noir#10103) chore(ACIR): inline `maybe_eq_predicate` (noir-lang/noir#10095) chore: use `u64` over `Field` in template program (noir-lang/noir#10096) chore: disallow slice arguments to blackbox functions (noir-lang/noir#10090) chore(brillig_vm): Separate fuzzing module (noir-lang/noir#10091) chore: ConstrainNotEqual requires acir predicate (noir-lang/noir#10062) chore: bump version of bb used in tests (noir-lang/noir#10093) chore: wrapping arithmetic tests (noir-lang/noir#9714) chore(brillig_vm): Foreign call module and test re-org (noir-lang/noir#10089) chore: add extra constraint folding pass (noir-lang/noir#9766) chore: refactor brillig_blocks (noir-lang/noir#10088) chore: add regression test for #9986 (noir-lang/noir#10087) chore: Release Noir(1.0.0-beta.14) (noir-lang/noir#9942) fix(tag_attr): keep whitespace tokens when parsing (noir-lang/noir#9981) fix: hoist and then deduplicate (noir-lang/noir#10047) chore: typos and some refactors in `acvm/src/pwg` (noir-lang/noir#10086) chore: add in hack for `public_dispatch` (noir-lang/noir#10084) fix(ssa): Avoid going through `i128` when casting signed to `u128` (noir-lang/noir#10045) chore: avoid zero bits range-checks (noir-lang/noir#10083) chore: bump external pinned commits (noir-lang/noir#10082) fix(stdlib): Only compute the garbage `embedded_curve_result` result if we know we will need it (noir-lang/noir#10077) fix(ssa): Keep defaults for values returned in the databus (noir-lang/noir#10042) chore: remove unused predicate from mem-op solver (noir-lang/noir#10079) chore(ACIR): snapshot tests for each instruction (noir-lang/noir#10071) fix: remove generic length from ECDSA message hash in stdlib (noir-lang/noir#10043) chore: validate that no jumps to function entry block exist (noir-lang/noir#10076) feat(brillig): Centralize memory layout policy and reorganize memory regions (noir-lang/noir#9985) chore(ci): fix permissions about publishing rustdoc (noir-lang/noir#10075) chore(ACVM): use Vec instead of Hash for memory blocks (noir-lang/noir#10072) feat(ssa): `constant_folding` with loop (noir-lang/noir#10019) chore: take truncate into account for bit size (noir-lang/noir#10059) chore: update check for `u128` overflow in `check_u128_mul_overflow` (noir-lang/noir#9998) chore: update check for field overflow in `check_u128_mul_overflow` (noir-lang/noir#9968) chore(ACIR): binary instructions snapshots (noir-lang/noir#10054) chore(acir): SliceRemove refactor (noir-lang/noir#10058) fix(fuzzer): Mark DivisionByZero with different types as equivalent (noir-lang/noir#10066) chore(fuzz): Remove `is_frontend_friendly` from the AST fuzzer (noir-lang/noir#10046) chore: use new ACIR syntax in docs, and some tests (noir-lang/noir#10057) fix(ssa): SSA interpreter to use the 2nd arg in `slice_refcount` (noir-lang/noir#10034) fix(ssa): SSA interpreter to return 0 for `Intrinsic::*RefCount` when constrained (noir-lang/noir#10033) chore(ssa_fuzzer): fix array get/set (noir-lang/noir#10031) fix(acir): Extend slice on dynamic insertion and compilation panic when flattening (noir-lang/noir#10051) chore(ACIR): extract convert_constrain_error helper (noir-lang/noir#10050) chore(ACIR): expand signed lt, div and mod in SSA (noir-lang/noir#10036) chore(ACIR): more consistent syntax and with less noise (noir-lang/noir#10014) chore(acir): Code gen tests for slice intrinsics (noir-lang/noir#10017) feat: parse and display SSA databus (noir-lang/noir#9991) fix(ssa): Handle partially removed `ArrayGet` groups of complex type during OOB checks (noir-lang/noir#10027) chore(acir): binary operations always have the same operand types (noir-lang/noir#10028) feat: Add Module::parent and Module::child_modules (noir-lang/noir#10005) chore: green light for ACVM optimisation (noir-lang/noir#10002) chore: unit test for brillig solver (greenlight ACVM execution) (noir-lang/noir#9967) chore(acir): avoid duplication when invoking brillig stdlib call (noir-lang/noir#10025) chore: Use 8 partitions for rust tests (noir-lang/noir#10026) chore: green light for ACVM execution audit (noir-lang/noir#9982) chore: greenlight for ACVM execution (PWG) (noir-lang/noir#9961) feat: optimize out noop casts on constants (noir-lang/noir#10024) fix(mem2reg): consider call return aliases (noir-lang/noir#10016) chore: bump external pinned commits (noir-lang/noir#10022) fix(parser): enforce left brace after match expression (noir-lang/noir#10018) chore(acir): Intrinsics and slice_ops modules as well as slice_ops doc comments (noir-lang/noir#10012) fix: signed division by -1 can overflow (noir-lang/noir#9976) chore(ci): fix external checks (noir-lang/noir#10009) chore(ci): add provenance attestations to npm packages (noir-lang/noir#10011) chore(ACIR): show all expressions as polynomials (noir-lang/noir#10007) chore: remove unused feature flag (noir-lang/noir#9993) chore(ci): fix docs breaking JS releases (noir-lang/noir#10010) chore(ssa_fuzzer): add external coverage registration (noir-lang/noir#9974) END_COMMIT_OVERRIDE
Automated pull of nightly from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec. BEGIN_COMMIT_OVERRIDE chore: Remove unnecessary allocation in `expr_with` (noir-lang/noir#10103) chore(ACIR): inline `maybe_eq_predicate` (noir-lang/noir#10095) chore: use `u64` over `Field` in template program (noir-lang/noir#10096) chore: disallow slice arguments to blackbox functions (noir-lang/noir#10090) chore(brillig_vm): Separate fuzzing module (noir-lang/noir#10091) chore: ConstrainNotEqual requires acir predicate (noir-lang/noir#10062) chore: bump version of bb used in tests (noir-lang/noir#10093) chore: wrapping arithmetic tests (noir-lang/noir#9714) chore(brillig_vm): Foreign call module and test re-org (noir-lang/noir#10089) chore: add extra constraint folding pass (noir-lang/noir#9766) chore: refactor brillig_blocks (noir-lang/noir#10088) chore: add regression test for #9986 (noir-lang/noir#10087) chore: Release Noir(1.0.0-beta.14) (noir-lang/noir#9942) fix(tag_attr): keep whitespace tokens when parsing (noir-lang/noir#9981) fix: hoist and then deduplicate (noir-lang/noir#10047) chore: typos and some refactors in `acvm/src/pwg` (noir-lang/noir#10086) chore: add in hack for `public_dispatch` (noir-lang/noir#10084) fix(ssa): Avoid going through `i128` when casting signed to `u128` (noir-lang/noir#10045) chore: avoid zero bits range-checks (noir-lang/noir#10083) chore: bump external pinned commits (noir-lang/noir#10082) fix(stdlib): Only compute the garbage `embedded_curve_result` result if we know we will need it (noir-lang/noir#10077) fix(ssa): Keep defaults for values returned in the databus (noir-lang/noir#10042) chore: remove unused predicate from mem-op solver (noir-lang/noir#10079) chore(ACIR): snapshot tests for each instruction (noir-lang/noir#10071) fix: remove generic length from ECDSA message hash in stdlib (noir-lang/noir#10043) chore: validate that no jumps to function entry block exist (noir-lang/noir#10076) feat(brillig): Centralize memory layout policy and reorganize memory regions (noir-lang/noir#9985) chore(ci): fix permissions about publishing rustdoc (noir-lang/noir#10075) chore(ACVM): use Vec instead of Hash for memory blocks (noir-lang/noir#10072) feat(ssa): `constant_folding` with loop (noir-lang/noir#10019) chore: take truncate into account for bit size (noir-lang/noir#10059) chore: update check for `u128` overflow in `check_u128_mul_overflow` (noir-lang/noir#9998) chore: update check for field overflow in `check_u128_mul_overflow` (noir-lang/noir#9968) chore(ACIR): binary instructions snapshots (noir-lang/noir#10054) chore(acir): SliceRemove refactor (noir-lang/noir#10058) fix(fuzzer): Mark DivisionByZero with different types as equivalent (noir-lang/noir#10066) chore(fuzz): Remove `is_frontend_friendly` from the AST fuzzer (noir-lang/noir#10046) chore: use new ACIR syntax in docs, and some tests (noir-lang/noir#10057) fix(ssa): SSA interpreter to use the 2nd arg in `slice_refcount` (noir-lang/noir#10034) fix(ssa): SSA interpreter to return 0 for `Intrinsic::*RefCount` when constrained (noir-lang/noir#10033) chore(ssa_fuzzer): fix array get/set (noir-lang/noir#10031) fix(acir): Extend slice on dynamic insertion and compilation panic when flattening (noir-lang/noir#10051) chore(ACIR): extract convert_constrain_error helper (noir-lang/noir#10050) chore(ACIR): expand signed lt, div and mod in SSA (noir-lang/noir#10036) chore(ACIR): more consistent syntax and with less noise (noir-lang/noir#10014) chore(acir): Code gen tests for slice intrinsics (noir-lang/noir#10017) feat: parse and display SSA databus (noir-lang/noir#9991) fix(ssa): Handle partially removed `ArrayGet` groups of complex type during OOB checks (noir-lang/noir#10027) chore(acir): binary operations always have the same operand types (noir-lang/noir#10028) feat: Add Module::parent and Module::child_modules (noir-lang/noir#10005) chore: green light for ACVM optimisation (noir-lang/noir#10002) chore: unit test for brillig solver (greenlight ACVM execution) (noir-lang/noir#9967) chore(acir): avoid duplication when invoking brillig stdlib call (noir-lang/noir#10025) chore: Use 8 partitions for rust tests (noir-lang/noir#10026) chore: green light for ACVM execution audit (noir-lang/noir#9982) chore: greenlight for ACVM execution (PWG) (noir-lang/noir#9961) feat: optimize out noop casts on constants (noir-lang/noir#10024) fix(mem2reg): consider call return aliases (noir-lang/noir#10016) chore: bump external pinned commits (noir-lang/noir#10022) fix(parser): enforce left brace after match expression (noir-lang/noir#10018) chore(acir): Intrinsics and slice_ops modules as well as slice_ops doc comments (noir-lang/noir#10012) fix: signed division by -1 can overflow (noir-lang/noir#9976) chore(ci): fix external checks (noir-lang/noir#10009) chore(ci): add provenance attestations to npm packages (noir-lang/noir#10011) chore(ACIR): show all expressions as polynomials (noir-lang/noir#10007) chore: remove unused feature flag (noir-lang/noir#9993) chore(ci): fix docs breaking JS releases (noir-lang/noir#10010) chore(ssa_fuzzer): add external coverage registration (noir-lang/noir#9974) END_COMMIT_OVERRIDE Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>

Description
Problem
Part of #10029
Summary
Additional Context
Given this program:
The ACIR we get is this:
It's huge! In the end, if we check what we do in ACIR (that is, the source code that produces this ACIR), it's understandable. The problem is that operations like "divide x by y" in ACIR result in some ACIR expressions that are then hard to reconstruct as "this is a division".
On the other hand, we start with this SSA:
Then now we transform it to this SSA:
It's also a lot of code but not as much as in ACIR, and what happens is easier to understand. Here we can see that we cast the values to their unsigned counterparts, then divide by 128 (presumably to check the sign). Then there's a comparison using these unsigned types and a couple of
xor, which need an explanation... but all of this is also what happened in ACIR but it was far less clear.Documentation
Check one:
PR Checklist
cargo fmton default settings.