Skip to content

fix(licm): Check whether the loop is executed when hoisting with a predicate#8546

Merged
TomAFrench merged 9 commits intomasterfrom
mv/check-loop-executed-for-control-dep-instructions
May 16, 2025
Merged

fix(licm): Check whether the loop is executed when hoisting with a predicate#8546
TomAFrench merged 9 commits intomasterfrom
mv/check-loop-executed-for-control-dep-instructions

Conversation

@vezenovm
Copy link
Contributor

Description

Problem*

Resolves #8319
Resolves #8521

Summary*

We were not checking whether the loop body is guaranteed to execute when hoisting with a predicate. This is logic we already were doing when simplifying loop bounds for instructions such as constrain and pure with predicate calls.

Additional Context

Documentation*

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [For Experimental Features] Documentation to be submitted in a separate PR.

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

@github-actions
Copy link
Contributor

github-actions bot commented May 16, 2025

Changes to Brillig bytecode sizes

Generated at commit: 0d817bb28176b1382a6f68bd8776a5cb10937c6b, compared to commit: ef6d8667c524cc07e02bdbd142ab16bee25f1581

🧾 Summary (10% most significant diffs)

Program Brillig opcodes (+/-) %
poseidon_bn254_hash_width_3_inliner_min +12 ❌ +0.25%
poseidonsponge_x5_254_inliner_zero +6 ❌ +0.21%

Full diff report 👇
Program Brillig opcodes (+/-) %
poseidon_bn254_hash_width_3_inliner_min 4,768 (+12) +0.25%
poseidonsponge_x5_254_inliner_zero 2,896 (+6) +0.21%
poseidonsponge_x5_254_inliner_min 3,023 (+6) +0.20%
regression_5252_inliner_zero 3,230 (+6) +0.19%
regression_5252_inliner_min 3,400 (+6) +0.18%

@github-actions
Copy link
Contributor

github-actions bot commented May 16, 2025

Changes to number of Brillig opcodes executed

Generated at commit: 0d817bb28176b1382a6f68bd8776a5cb10937c6b, compared to commit: ef6d8667c524cc07e02bdbd142ab16bee25f1581

🧾 Summary (10% most significant diffs)

Program Brillig opcodes (+/-) %
loop_invariant_regression_inliner_min +366 ❌ +31.07%
poseidon_bn254_hash_width_3_inliner_min +617 ❌ +0.37%

Full diff report 👇
Program Brillig opcodes (+/-) %
loop_invariant_regression_inliner_min 1,544 (+366) +31.07%
poseidon_bn254_hash_width_3_inliner_min 168,481 (+617) +0.37%
regression_5252_inliner_zero 907,033 (+3,160) +0.35%
poseidonsponge_x5_254_inliner_zero 182,199 (+632) +0.35%
regression_5252_inliner_min 918,946 (+3,160) +0.35%
poseidonsponge_x5_254_inliner_min 184,116 (+632) +0.34%

@vezenovm vezenovm marked this pull request as ready for review May 16, 2025 11:43
@vezenovm vezenovm requested a review from a team May 16, 2025 11:43
@vezenovm vezenovm added the bench-show Display benchmark results on PR label May 16, 2025
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACVM Benchmarks

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
purely_sequential_opcodes 262202 ns/iter (± 1029) 263405 ns/iter (± 406) 1.00
perfectly_parallel_opcodes 234101 ns/iter (± 4616) 232559 ns/iter (± 2832) 1.01
perfectly_parallel_batch_inversion_opcodes 3571424 ns/iter (± 34131) 3570602 ns/iter (± 7008) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compilation Time

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
private-kernel-inner 2.68 s 2.362 s 1.13
private-kernel-reset 6.636 s 6.398 s 1.04
private-kernel-tail 1.098 s 1.058 s 1.04
rollup-base-private 17.68 s 16.46 s 1.07
rollup-base-public 13.78 s 12.42 s 1.11
rollup-block-root-empty 1.308 s 1.298 s 1.01
rollup-block-root-single-tx 134 s 126 s 1.06
rollup-block-root 125 s 126 s 0.99
rollup-merge 1.086 s 1.16 s 0.94
rollup-root 1.616 s 1.728 s 0.94
semaphore-depth-10 0.844 s 0.836 s 1.01

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Artifact Size

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
private-kernel-inner 1127.2 KB 1127.2 KB 1
private-kernel-reset 2051.1 KB 2051.1 KB 1
private-kernel-tail 583.2 KB 583.2 KB 1
rollup-base-private 5123.3 KB 5123.3 KB 1
rollup-base-public 3941.9 KB 3941.9 KB 1
rollup-block-root-empty 256.8 KB 256.8 KB 1
rollup-block-root-single-tx 25679 KB 25679 KB 1
rollup-block-root 25706.3 KB 25706.3 KB 1
rollup-merge 181.7 KB 181.7 KB 1
rollup-root 473.4 KB 473.4 KB 1
semaphore-depth-10 636.4 KB 636.4 KB 1

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Execution Time

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
private-kernel-inner 0.029 s 0.028 s 1.04
private-kernel-reset 0.159 s 0.158 s 1.01
private-kernel-tail 0.011 s 0.011 s 1
rollup-base-private 0.309 s 0.307 s 1.01
rollup-base-public 0.195 s 0.192 s 1.02
rollup-block-root 11.4 s 11.1 s 1.03
rollup-merge 0.004 s 0.004 s 1
rollup-root 0.013 s 0.013 s 1
semaphore-depth-10 0.019 s 0.02 s 0.95

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Suite Duration

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
test_report_AztecProtocol_aztec-packages_noir-projects_aztec-nr 66 s 65 s 1.02
test_report_AztecProtocol_aztec-packages_noir-projects_noir-contracts 95 s 95 s 1
test_report_AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_blob 41 s 43 s 0.95
test_report_AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_private-kernel-lib 191 s 190 s 1.01
test_report_AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_rollup-lib 194 s 187 s 1.04
test_report_AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_types 60 s 60 s 1
test_report_noir-lang_noir-bignum_ 376 s 372 s 1.01
test_report_noir-lang_noir_bigcurve_ 221 s 220 s 1.00
test_report_noir-lang_sha512_ 30 s 30 s 1
test_report_zkpassport_noir_rsa_ 24 s 23 s 1.04

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compilation Memory

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
private-kernel-inner 316.49 MB 316.49 MB 1
private-kernel-reset 572.29 MB 572.29 MB 1
private-kernel-tail 231.41 MB 231.42 MB 1.00
rollup-base-private 1440 MB 1440 MB 1
rollup-base-public 1470 MB 1470 MB 1
rollup-block-root-empty 402.97 MB 402.96 MB 1.00
rollup-block-root-single-tx 7220 MB 7220 MB 1
rollup-block-root 7220 MB 7220 MB 1
rollup-merge 385.02 MB 385.01 MB 1.00
rollup-root 445.92 MB 445.93 MB 1.00
semaphore_depth_10 128.47 MB 128.47 MB 1

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Execution Memory

Details
Benchmark suite Current: 8055a1e Previous: ef6d866 Ratio
private-kernel-inner 241.27 MB 241.27 MB 1
private-kernel-reset 263.53 MB 263.53 MB 1
private-kernel-tail 216.76 MB 216.76 MB 1
rollup-base-private 549.25 MB 549.25 MB 1
rollup-base-public 541.7 MB 541.7 MB 1
rollup-block-root 1450 MB 1450 MB 1
rollup-merge 370.96 MB 370.96 MB 1
rollup-root 376.89 MB 376.89 MB 1
semaphore_depth_10 93.04 MB 93.04 MB 1

This comment was automatically generated by workflow using github-action-benchmark.

vezenovm and others added 3 commits May 16, 2025 09:08
Co-authored-by: Akosh Farkash <aakoshh@gmail.com>
…ol-dep-instructions' into mv/check-loop-executed-for-control-dep-instructions
Copy link
Contributor

@aakoshh aakoshh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was quick 👏

@TomAFrench TomAFrench enabled auto-merge May 16, 2025 13:28
@TomAFrench TomAFrench added this pull request to the merge queue May 16, 2025
Merged via the queue into master with commit 89cdf76 May 16, 2025
118 checks passed
@TomAFrench TomAFrench deleted the mv/check-loop-executed-for-control-dep-instructions branch May 16, 2025 13:52
github-merge-queue bot pushed a commit to AztecProtocol/aztec-packages that referenced this pull request May 22, 2025
Automated pull of nightly from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
fix(licm): Account for nested loops being control dependent when
analyzing outer loops (noir-lang/noir#8593)
chore(refactor): Switch unreachable function removal to use centralized
call graph (noir-lang/noir#8578)
chore(test): Allow lambdas in fuzzing
(noir-lang/noir#8584)
chore: use insta for execution_success stdout
(noir-lang/noir#8576)
chore: use generator instead of zero for ec-add predicate
(noir-lang/noir#8552)
fix: use predicate expression as binary result
(noir-lang/noir#8583)
fix(ssa): Do not generate apply functions when no lambda variants exist
(noir-lang/noir#8573)
chore: put `nargo expand` snapshosts in the same directory
(noir-lang/noir#8577)
chore: Use FxHashMap for TypeBindings
(noir-lang/noir#8574)
chore(experimental): use larger stack size for parsing
(noir-lang/noir#8347)
chore: use insta snapshots for compile_failure stderr
(noir-lang/noir#8569)
chore(inlining): Mark functions with <= 10 instructions and no control
flow as inline always (noir-lang/noir#8533)
chore(ssa): Add weighted edges to call graph, move callers and callees
methods to call graph (noir-lang/noir#8513)
fix(frontend): Override to allow empty array input
(noir-lang/noir#8568)
fix: avoid logging all unused params in DIE pass
(noir-lang/noir#8566)
chore: bump external pinned commits
(noir-lang/noir#8562)
chore(deps): bump base-x from 3.0.9 to 3.0.11
(noir-lang/noir#8555)
chore(fuzz): Call function pointers
(noir-lang/noir#8531)
feat: C++ codegen for msgpack
(noir-lang/noir#7716)
feat(performance): brillig array set optimization
(noir-lang/noir#8550)
chore(fuzz): AST fuzzer to use function valued arguments (Part 1)
(noir-lang/noir#8514)
fix(licm): Check whether the loop is executed when hoisting with a
predicate (noir-lang/noir#8546)
feat: Implement $crate (noir-lang/noir#8537)
fix: add offset to ArrayGet
(noir-lang/noir#8536)
chore: remove some unused enum variants and functions
(noir-lang/noir#8538)
fix: disallow `()` in entry points
(noir-lang/noir#8529)
chore: Remove println in ssa interpreter
(noir-lang/noir#8528)
fix: don't overflow when casting signed value to u128
(noir-lang/noir#8526)
chore(performance): Enable hoisting pure with predicate calls
(noir-lang/noir#8522)
feat(fuzz): AST fuzzing with SSA interpreter
(noir-lang/noir#8436)
chore: Add u1 ops to interpreter, convert Value panics to errors
(noir-lang/noir#8469)
chore: Release Noir(1.0.0-beta.6)
(noir-lang/noir#8438)
chore(fuzz): AST generator to add `ctx_limit` to all functions
(noir-lang/noir#8507)
fix(inlining): Use centralized CallGraph structure for inline info
computation (noir-lang/noir#8489)
fix: remove private builtins from `Field` impl
(noir-lang/noir#8496)
feat: primitive types are no longer keywords
(noir-lang/noir#8470)
fix: parenthesized pattern, and correct 1-element tuple printing
(noir-lang/noir#8482)
fix: fix visibility of methods in `std::meta`
(noir-lang/noir#8497)
fix: Change `can_be_main` to be recursive
(noir-lang/noir#8501)
chore: add SSA interpreter test for higher order functions
(noir-lang/noir#8486)
fix(frontend)!: Ban zero sized arrays and strings as program input
(noir-lang/noir#8491)
fix!: remove `to_be_radix` and `to_le_radix` from stdlib interface
(noir-lang/noir#8495)
END_COMMIT_OVERRIDE

---------

Co-authored-by: AztecBot <tech@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
AztecBot added a commit to AztecProtocol/aztec-nr that referenced this pull request May 23, 2025
Automated pull of nightly from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
fix(licm): Account for nested loops being control dependent when
analyzing outer loops (noir-lang/noir#8593)
chore(refactor): Switch unreachable function removal to use centralized
call graph (noir-lang/noir#8578)
chore(test): Allow lambdas in fuzzing
(noir-lang/noir#8584)
chore: use insta for execution_success stdout
(noir-lang/noir#8576)
chore: use generator instead of zero for ec-add predicate
(noir-lang/noir#8552)
fix: use predicate expression as binary result
(noir-lang/noir#8583)
fix(ssa): Do not generate apply functions when no lambda variants exist
(noir-lang/noir#8573)
chore: put `nargo expand` snapshosts in the same directory
(noir-lang/noir#8577)
chore: Use FxHashMap for TypeBindings
(noir-lang/noir#8574)
chore(experimental): use larger stack size for parsing
(noir-lang/noir#8347)
chore: use insta snapshots for compile_failure stderr
(noir-lang/noir#8569)
chore(inlining): Mark functions with <= 10 instructions and no control
flow as inline always (noir-lang/noir#8533)
chore(ssa): Add weighted edges to call graph, move callers and callees
methods to call graph (noir-lang/noir#8513)
fix(frontend): Override to allow empty array input
(noir-lang/noir#8568)
fix: avoid logging all unused params in DIE pass
(noir-lang/noir#8566)
chore: bump external pinned commits
(noir-lang/noir#8562)
chore(deps): bump base-x from 3.0.9 to 3.0.11
(noir-lang/noir#8555)
chore(fuzz): Call function pointers
(noir-lang/noir#8531)
feat: C++ codegen for msgpack
(noir-lang/noir#7716)
feat(performance): brillig array set optimization
(noir-lang/noir#8550)
chore(fuzz): AST fuzzer to use function valued arguments (Part 1)
(noir-lang/noir#8514)
fix(licm): Check whether the loop is executed when hoisting with a
predicate (noir-lang/noir#8546)
feat: Implement $crate (noir-lang/noir#8537)
fix: add offset to ArrayGet
(noir-lang/noir#8536)
chore: remove some unused enum variants and functions
(noir-lang/noir#8538)
fix: disallow `()` in entry points
(noir-lang/noir#8529)
chore: Remove println in ssa interpreter
(noir-lang/noir#8528)
fix: don't overflow when casting signed value to u128
(noir-lang/noir#8526)
chore(performance): Enable hoisting pure with predicate calls
(noir-lang/noir#8522)
feat(fuzz): AST fuzzing with SSA interpreter
(noir-lang/noir#8436)
chore: Add u1 ops to interpreter, convert Value panics to errors
(noir-lang/noir#8469)
chore: Release Noir(1.0.0-beta.6)
(noir-lang/noir#8438)
chore(fuzz): AST generator to add `ctx_limit` to all functions
(noir-lang/noir#8507)
fix(inlining): Use centralized CallGraph structure for inline info
computation (noir-lang/noir#8489)
fix: remove private builtins from `Field` impl
(noir-lang/noir#8496)
feat: primitive types are no longer keywords
(noir-lang/noir#8470)
fix: parenthesized pattern, and correct 1-element tuple printing
(noir-lang/noir#8482)
fix: fix visibility of methods in `std::meta`
(noir-lang/noir#8497)
fix: Change `can_be_main` to be recursive
(noir-lang/noir#8501)
chore: add SSA interpreter test for higher order functions
(noir-lang/noir#8486)
fix(frontend)!: Ban zero sized arrays and strings as program input
(noir-lang/noir#8491)
fix!: remove `to_be_radix` and `to_le_radix` from stdlib interface
(noir-lang/noir#8495)
END_COMMIT_OVERRIDE

---------

Co-authored-by: AztecBot <tech@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Thunkar pushed a commit to AztecProtocol/aztec-packages that referenced this pull request May 23, 2025
Automated pull of nightly from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
fix(licm): Account for nested loops being control dependent when
analyzing outer loops (noir-lang/noir#8593)
chore(refactor): Switch unreachable function removal to use centralized
call graph (noir-lang/noir#8578)
chore(test): Allow lambdas in fuzzing
(noir-lang/noir#8584)
chore: use insta for execution_success stdout
(noir-lang/noir#8576)
chore: use generator instead of zero for ec-add predicate
(noir-lang/noir#8552)
fix: use predicate expression as binary result
(noir-lang/noir#8583)
fix(ssa): Do not generate apply functions when no lambda variants exist
(noir-lang/noir#8573)
chore: put `nargo expand` snapshosts in the same directory
(noir-lang/noir#8577)
chore: Use FxHashMap for TypeBindings
(noir-lang/noir#8574)
chore(experimental): use larger stack size for parsing
(noir-lang/noir#8347)
chore: use insta snapshots for compile_failure stderr
(noir-lang/noir#8569)
chore(inlining): Mark functions with <= 10 instructions and no control
flow as inline always (noir-lang/noir#8533)
chore(ssa): Add weighted edges to call graph, move callers and callees
methods to call graph (noir-lang/noir#8513)
fix(frontend): Override to allow empty array input
(noir-lang/noir#8568)
fix: avoid logging all unused params in DIE pass
(noir-lang/noir#8566)
chore: bump external pinned commits
(noir-lang/noir#8562)
chore(deps): bump base-x from 3.0.9 to 3.0.11
(noir-lang/noir#8555)
chore(fuzz): Call function pointers
(noir-lang/noir#8531)
feat: C++ codegen for msgpack
(noir-lang/noir#7716)
feat(performance): brillig array set optimization
(noir-lang/noir#8550)
chore(fuzz): AST fuzzer to use function valued arguments (Part 1)
(noir-lang/noir#8514)
fix(licm): Check whether the loop is executed when hoisting with a
predicate (noir-lang/noir#8546)
feat: Implement $crate (noir-lang/noir#8537)
fix: add offset to ArrayGet
(noir-lang/noir#8536)
chore: remove some unused enum variants and functions
(noir-lang/noir#8538)
fix: disallow `()` in entry points
(noir-lang/noir#8529)
chore: Remove println in ssa interpreter
(noir-lang/noir#8528)
fix: don't overflow when casting signed value to u128
(noir-lang/noir#8526)
chore(performance): Enable hoisting pure with predicate calls
(noir-lang/noir#8522)
feat(fuzz): AST fuzzing with SSA interpreter
(noir-lang/noir#8436)
chore: Add u1 ops to interpreter, convert Value panics to errors
(noir-lang/noir#8469)
chore: Release Noir(1.0.0-beta.6)
(noir-lang/noir#8438)
chore(fuzz): AST generator to add `ctx_limit` to all functions
(noir-lang/noir#8507)
fix(inlining): Use centralized CallGraph structure for inline info
computation (noir-lang/noir#8489)
fix: remove private builtins from `Field` impl
(noir-lang/noir#8496)
feat: primitive types are no longer keywords
(noir-lang/noir#8470)
fix: parenthesized pattern, and correct 1-element tuple printing
(noir-lang/noir#8482)
fix: fix visibility of methods in `std::meta`
(noir-lang/noir#8497)
fix: Change `can_be_main` to be recursive
(noir-lang/noir#8501)
chore: add SSA interpreter test for higher order functions
(noir-lang/noir#8486)
fix(frontend)!: Ban zero sized arrays and strings as program input
(noir-lang/noir#8491)
fix!: remove `to_be_radix` and `to_le_radix` from stdlib interface
(noir-lang/noir#8495)
END_COMMIT_OVERRIDE

---------

Co-authored-by: AztecBot <tech@aztecprotocol.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bench-show Display benchmark results on PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Brillig divides by zero in a loop that never runs Brillig: Assertion failed with minimal inliner aggressiveness only

3 participants