Skip to content

fix(ssa): let mem2reg ignore make_arrays whose result is unused - #14167

Open
AztecBot wants to merge 3 commits into
masterfrom
cb/mem2reg-dead-make-array-refs
Open

AztecBot wants to merge 3 commits into
masterfrom
cb/mem2reg-dead-make-array-refs

Conversation

@AztecBot

@AztecBot AztecBot commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

The nightly AST fuzzer failed min_vs_full on seed 0x80df4d0e00100000:

Store instruction found in ACIR function 'main': the address v95 of type &mut i16 was not promoted by mem2reg, so a memory operation reached ACIR generation

It reduces to an ordinary program, with no dynamic or out-of-bounds indices:

fn main() {
    let _t = &[&[&[&1]]];
}

nargo compile panics on this on master. One level less nesting compiles.

Root cause

Mem2reg treats any non-load/store use of an address as escaping, including being an element of a make_array whose result is never used. Only DIE removes such an array. So a nested aggregate of references is unwrapped one level per DIE→Mem2Reg pair in the pipeline. With three or more levels the pipeline runs out of pairs, and the innermost allocate/store reach ACIR generation.

#13478 hit the same mechanism and fixed only the generator. It assumed the shape needed a dynamic index to keep the aggregate alive. That assumption doesn't hold: the aggregate can be entirely dead and just deeply nested.

Full RCA: https://gist.github.com/AztecBot/4db3b091bbaee2281497a5145d0782fc

Fix

On each iteration of mem2reg's existing loop, find_dead_make_arrays collects the make_arrays whose result has no use. Uses counted are any instruction (including other make_arrays), any terminator, and the databus, since call-data arrays are referenced only through dfg.data_bus.

  • Eligibility collection skips those arrays, so a reference held only by one is promotable.
  • commit removes them, so the promoted allocation leaves no dangling operand.
  • The loop keeps going while there are dead arrays to remove, even when no variable is eligible yet. That covers arrays nested with no & in between, such as [[&x]].

Removing one level leaves the next one unused, so a single mem2reg run collapses a nested tree of any depth. The extra cost is one linear scan per mem2reg iteration, the same order as the existing eligibility scan.

Alternatives considered, including a pipeline-level DIE↔Mem2Reg fixed point that was briefly on this branch: this gist.

Tests

The first commit adds the tests and records the buggy snapshot.

  • promotes_references_held_only_by_an_unused_make_array: on master every allocate/store survives mem2reg(). With the fix only return remains.
  • promotes_reference_held_only_by_unused_nested_arrays: [[&x]] shape. Fails without the loop-condition change.
  • keeps_references_held_by_a_used_make_array: a read-through array stays unchanged.
  • keeps_call_data_make_array_not_read_by_any_instruction: fails (dangling call-data value) if the databus values are not counted as used.
  • test_programs/compile_success_empty/nested_unused_references: on master it panics with the CI message.

Ran locally: cargo fmt --check, cargo clippy -p noirc_evaluator --all-targets -D warnings, cargo test -p noirc_evaluator (2235 passed), the nested_unused_references execute tests, and a replay of seed 0x80df4d0e00100000 on min_vs_full (passes). The full cargo test --release -p nargo_cli --test execute (10273 passed) ran on this mem2reg change before the [[&x]] unit test was added; that test is the only addition since. The rest is with CI.


Created by claudebox · group: slackbot · requested by Ary Borenszweig · Slack thread

@AztecBot AztecBot added claude-review Adversarial ClaudeBox review pending claudebox labels Nov 13, 2026
@asterite asterite added the bench-show Display benchmark results on PR label Nov 13, 2026
@AztecBot AztecBot changed the title fix(ssa): let mem2reg promote references held only by unused arrays fix(ssa): alternate DIE and mem2reg until no allocation is promoted Nov 13, 2026

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
purely_sequential_opcodes 98356 ns/iter (± 347) 181066 ns/iter (± 548) 0.54
perfectly_parallel_opcodes 87594 ns/iter (± 793) 152827 ns/iter (± 2558) 0.57
perfectly_parallel_batch_inversion_opcodes 2360008 ns/iter (± 7565) 2402834 ns/iter (± 5044) 0.98

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Brillig Artifact Size

Details
Benchmark suite Current: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 865 KB 865 KB 1
private-kernel-reset-tail 954.2 KB 954.2 KB 1
private-kernel-reset 703.7 KB 703.7 KB 1
rollup-block-root-no-txs 399.6 KB 399.6 KB 1
rollup-block-root-single-tx 419.8 KB 419.8 KB 1
rollup-block-root 518.3 KB 518.3 KB 1
rollup-checkpoint-merge 321.3 KB 321.3 KB 1
rollup-checkpoint-root-single-block 779 KB 779 KB 1
rollup-checkpoint-root 817.1 KB 817.1 KB 1
rollup-root 526.4 KB 526.4 KB 1
rollup-tx-base-private 803 KB 803 KB 1
rollup-tx-base-public 963.3 KB 963.3 KB 1
rollup-tx-merge 310.2 KB 310.2 KB 1
semaphore-depth-10 2080.3 KB 2080.3 KB 1
sha512-100-bytes 154.4 KB 154.4 KB 1

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 2.58 s 3.198 s 0.81
private-kernel-reset-tail 8.85 s 10.9 s 0.81
private-kernel-reset 6.406 s 7.106 s 0.90
rollup-block-root-no-txs 3.376 s 3.488 s 0.97
rollup-block-root-single-tx 3.01 s 3.65 s 0.82
rollup-block-root 3.7 s 3.97 s 0.93
rollup-checkpoint-merge 3.568 s 3.212 s 1.11
rollup-checkpoint-root-single-block 223 s 173 s 1.29
rollup-checkpoint-root 284 s 228 s 1.25
rollup-root 2.046 s 2.664 s 0.77
rollup-tx-base-private 18.82 s 16.46 s 1.14
rollup-tx-base-public 18.78 s 15.44 s 1.22
rollup-tx-merge 1.986 s 2.644 s 0.75
semaphore-depth-10 0.859 s 0.906 s 0.95
sha512-100-bytes 1.432 s 2.059 s 0.70

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 0.03 s 0.033 s 0.91
private-kernel-reset-tail 0.14 s 0.176 s 0.80
private-kernel-reset 0.098 s 0.115 s 0.85
rollup-block-root-no-txs 0.012 s 0.013 s 0.92
rollup-block-root-single-tx 0.013 s 0.015 s 0.87
rollup-block-root 0.016 s 0.016 s 1
rollup-checkpoint-merge 0.003 s 0.002 s 1.50
rollup-checkpoint-root-single-block 9.566 s 5.336 s 1.79
rollup-checkpoint-root 9.962 s 9.992 s 1.00
rollup-root 0.002 s 0.002 s 1
rollup-tx-base-private 0.285 s 0.241 s 1.18
rollup-tx-base-public 0.224 s 0.222 s 1.01
rollup-tx-merge 0.001 s 0.002 s 0.50
semaphore-depth-10 0.009 s 0.008 s 1.13
sha512-100-bytes 0.05 s 0.097 s 0.52

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Brillig Execution Time

Details
Benchmark suite Current: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 0.024 s 0.024 s 1
private-kernel-reset-tail 0.038 s 0.051 s 0.75
private-kernel-reset 0.006 s 0.008 s 0.75
rollup-block-root-no-txs 0.008 s 0.009 s 0.89
rollup-block-root-single-tx 0.009 s 0.012 s 0.75
rollup-block-root 0.01 s 0.011 s 0.91
rollup-checkpoint-merge 0.001 s 0.001 s 1
rollup-root 0.001 s 0.001 s 1
rollup-tx-base-private 0.046 s 0.039 s 1.18
rollup-tx-base-public 0.028 s 0.027 s 1.04
rollup-tx-merge 0.001 s 0.001 s 1
semaphore-depth-10 0.007 s 0.007 s 1
sha512-100-bytes 0.007 s 0.011 s 0.64

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Brillig Compilation Time

Details
Benchmark suite Current: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 1.848 s 2.292 s 0.81
private-kernel-reset-tail 2.1 s 2.73 s 0.77
private-kernel-reset 1.856 s 2.208 s 0.84
rollup-block-root-no-txs 2.926 s 3.008 s 0.97
rollup-block-root-single-tx 2.6 s 3.28 s 0.79
rollup-block-root 3.25 s 3.48 s 0.93
rollup-checkpoint-merge 3.518 s 3.268 s 1.08
rollup-checkpoint-root-single-block 4.61 s 2.65 s 1.74
rollup-checkpoint-root 4.72 s 4.61 s 1.02
rollup-root 2.066 s 2.636 s 0.78
rollup-tx-base-private 3.484 s 2.766 s 1.26
rollup-tx-base-public 3.008 s 2.884 s 1.04
rollup-tx-merge 2.04 s 2.582 s 0.79
semaphore-depth-10 0.447 s 0.476 s 0.94
sha512-100-bytes 0.273 s 0.426 s 0.64

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 1150.4 KB 1150.4 KB 1
private-kernel-reset-tail 2658.2 KB 2658.2 KB 1
private-kernel-reset 2101.9 KB 2101.9 KB 1
rollup-block-root-no-txs 467.5 KB 467.5 KB 1
rollup-block-root-single-tx 499.4 KB 499.4 KB 1
rollup-block-root 611.3 KB 611.3 KB 1
rollup-checkpoint-merge 471.3 KB 471.3 KB 1
rollup-checkpoint-root-single-block 30740.4 KB 30740.4 KB 1
rollup-checkpoint-root 30783.6 KB 30783.6 KB 1
rollup-root 510.5 KB 510.5 KB 1
rollup-tx-base-private 4635.2 KB 4635.2 KB 1
rollup-tx-base-public 5032.5 KB 5032.5 KB 1
rollup-tx-merge 273.4 KB 273.4 KB 1
semaphore-depth-10 509.4 KB 509.4 KB 1
sha512-100-bytes 453.8 KB 453.8 KB 1

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Elaboration Time

Details
Benchmark suite Current: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 1.314 s 1.6 s 0.82
private-kernel-reset-tail 1.3 s 1.71 s 0.76
private-kernel-reset 1.292 s 1.632 s 0.79
rollup-block-root-no-txs 2.488 s 2.624 s 0.95
rollup-block-root-single-tx 2.26 s 2.81 s 0.80
rollup-block-root 2.8 s 2.93 s 0.96
rollup-checkpoint-merge 3.088 s 2.792 s 1.11
rollup-checkpoint-root-single-block 2.85 s 1.56 s 1.83
rollup-checkpoint-root 2.85 s 2.73 s 1.04
rollup-root 1.7 s 2.246 s 0.76
rollup-tx-base-private 2.826 s 2.22 s 1.27
rollup-tx-base-public 2.352 s 2.226 s 1.06
rollup-tx-merge 1.682 s 2.28 s 0.74
semaphore-depth-10 0.328 s 0.348 s 0.94
sha512-100-bytes 0.209 s 0.314 s 0.67

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Opcode count

Details
Benchmark suite Current: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 17676 opcodes 17676 opcodes 1
private-kernel-reset-tail 89698 opcodes 89698 opcodes 1
private-kernel-reset 75108 opcodes 75108 opcodes 1
rollup-block-root-no-txs 9060 opcodes 9060 opcodes 1
rollup-block-root-single-tx 9126 opcodes 9126 opcodes 1
rollup-block-root 10312 opcodes 10312 opcodes 1
rollup-checkpoint-merge 1278 opcodes 1278 opcodes 1
rollup-checkpoint-root-single-block 1388084 opcodes 1388084 opcodes 1
rollup-checkpoint-root 1389277 opcodes 1389277 opcodes 1
rollup-root 1560 opcodes 1560 opcodes 1
rollup-tx-base-private 241254 opcodes 241254 opcodes 1
rollup-tx-base-public 262286 opcodes 262286 opcodes 1
rollup-tx-merge 1306 opcodes 1306 opcodes 1
semaphore-depth-10 5699 opcodes 5699 opcodes 1
sha512-100-bytes 13173 opcodes 13173 opcodes 1

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
test_report_AztecProtocol_aztec-packages_noir-projects_fnd_noir-protocol-circuits_crates_blob 184 s 158 s 1.16
test_report_AztecProtocol_aztec-packages_noir-projects_fnd_noir-protocol-circuits_crates_private-kernel-lib 408 s 392 s 1.04
test_report_AztecProtocol_aztec-packages_noir-projects_fnd_noir-protocol-circuits_crates_types 35 s 33 s 1.06
test_report_noir-lang_noir-bignum_ 69 s 54 s 1.28
test_report_noir-lang_noir_bigcurve_ 333 s 506 s 0.66
test_report_noir-lang_noir_json_parser_ 6 s 7 s 0.86
test_report_noir-lang_sha256_ 23 s 24 s 0.96
test_report_noir-lang_sha512_ 11 s 13 s 0.85
test_report_zkpassport_noir-ecdsa_ 3 s 2 s 1.50
test_report_zkpassport_noir_rsa_ 2 s 1 s 2

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

@AztecBot AztecBot changed the title fix(ssa): alternate DIE and mem2reg until no allocation is promoted fix(ssa): let mem2reg ignore make_arrays whose result is unused Nov 13, 2026

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 297.25 MB 297.25 MB 1
private-kernel-reset-tail 359.58 MB 359.58 MB 1
private-kernel-reset 336.18 MB 336.18 MB 1
rollup-block-root-no-txs 542.53 MB 542.53 MB 1
rollup-block-root-single-tx 542.53 MB 542.53 MB 1
rollup-block-root 542.53 MB 542.53 MB 1
rollup-checkpoint-merge 542.53 MB 542.53 MB 1
rollup-checkpoint-root-single-block 7960 MB 7960 MB 1
rollup-checkpoint-root 7960 MB 7960 MB 1
rollup-root 542.53 MB 542.53 MB 1
rollup-tx-base-private 608.74 MB 608.74 MB 1
rollup-tx-base-public 546.59 MB 546.59 MB 1
rollup-tx-merge 542.53 MB 542.53 MB 1
semaphore_depth_10 86.24 MB 86.24 MB 1
sha512_100_bytes 101.18 MB 101.19 MB 1.00

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

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

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: 6e5c05c Previous: e5a1160 Ratio
private-kernel-inner 309.72 MB 309.72 MB 1
private-kernel-reset-tail 352.29 MB 352.29 MB 1
private-kernel-reset 339.09 MB 339.09 MB 1
rollup-block-root 546.62 MB 546.62 MB 1
rollup-checkpoint-merge 543.91 MB 543.91 MB 1
rollup-checkpoint-root-single-block 1280 MB 1280 MB 1
rollup-checkpoint-root 1280 MB 1280 MB 1
rollup-root 544.14 MB 544.14 MB 1
rollup-tx-base-private 645.27 MB 645.27 MB 1
rollup-tx-base-public 656.54 MB 656.54 MB 1
rollup-tx-merge 543.31 MB 543.31 MB 1
semaphore_depth_10 89.1 MB 89.1 MB 1
sha512_100_bytes 80.85 MB 80.85 MB 1

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

@asterite
asterite force-pushed the cb/mem2reg-dead-make-array-refs branch from e2ba9c6 to 6e5c05c Compare November 13, 2026 14:31
@asterite
asterite marked this pull request as ready for review November 13, 2026 14:46

This branch has not been deployed

No deployments
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 claude-review Adversarial ClaudeBox review pending claudebox

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants