Skip to content

feat(passes): preserve aggregate ternary instructions - #29349

Draft
mohammadfawaz wants to merge 3 commits into
masterfrom
mohammadfawaz/ternary_ops
Draft

mohammadfawaz wants to merge 3 commits into
masterfrom
mohammadfawaz/ternary_ops

Conversation

@mohammadfawaz

@mohammadfawaz mohammadfawaz commented Apr 18, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Preserve ternaries over arrays and plaintext structs as single Aleo ternary instructions. Keep tuple and record ternaries split into element or field selections. Array, struct, and identifier ternaries require ConsensusVersion::V23.

Update the snarkVM dependency to PR #3222, commit 933acedd6. Support V23 in CLI version selection. Align the existing RocksDB dependency with the selected snarkVM revision. Update the fixtures for current constructor, execution-harness, and consensus-version requirements.

Measurement method

Compare this PR with master at fcbebc7db6. Use identical source inputs and build options for both compilers. Each percentage is the change in total bytes for its stated corpus.

Regenerate compiler expectations with UPDATE_EXPECT=1 cargo test -p leo-compiler --lib test_compiler::test_compiler -- --exact --nocapture. For external programs, run leo build --network testnet --offline from fresh source copies and measure the main program's emitted .aleo text file. Exclude imported bytecode from those program totals.

Compiler expectation files

Compare the 1,675 fixture-backed output paths present in both trees. Exclude the 11 new compiler fixtures and nine orphaned expectation files. These totals include diagnostics and output from both import modes; they measure expectation files, not only Aleo bytecode.

Metric Before After Change
Total bytes 2,126,672 2,107,529 -19,143 (-0.90%)
Lines, counted by LF bytes 65,369 65,007 -362
Changed files 32 of 1,675

The subset with bytecode and no errors contains 1,113 files. Its size changes from 1,570,011 to 1,553,197 bytes, a reduction of 16,814 bytes (1.07%). Its line count changes from 51,393 to 51,073, and 29 files change.

Changes for every compiler path listed in the previous description
Output under tests/expectations/compiler/ Before bytes After bytes Change
function/flatten_test.out 9,679 4,077 -5,602
storage/external_storage.out 35,835 32,620 -3,215
option/unwrap_or_deep.out 5,925 2,765 -3,160
storage/aggregates.out 11,158 8,257 -2,901
option/in_modules.out 11,557 9,235 -2,322
function/flatten_arrays.out 2,292 1,038 -1,254
examples/tictactoe.out 5,635 4,559 -1,076
option/implicit_wrapping.out 7,908 7,248 -660
storage/primitives.out 4,805 5,361 +556
storage/signed.out 4,339 4,895 +556
storage/unsigned.out 4,334 4,890 +556
storage/external_storage_multi_deps.out 7,010 7,788 +778

Aggregate selection can retain both branch constructions. Some storage outputs increase in size, including the four listed above.

Bytecode impact: leo-examples

Use all 34 programs from leo-examples at 03554ec3.

Metric Before After Change
Total bytes 132,465 131,341 -1,124 (-0.85%)
Total lines 4,286 4,262 -24
Changed programs 1 of 34

tictactoe changes from 6,525 to 5,401 bytes (-17.23%) and from 207 to 183 lines. Its output contains two aggregate ternaries, both over Board values. The other 33 programs are byte-identical, checked by SHA-256.

Bytecode impact: amm-v3

Use the development snapshot at 8d161722. It contains seven primary source programs, five test programs, and two libraries. Keep the pinned ARCs dependency at bf0a4e7aa9cb155751aa6b8aebe7c9162e2a7a5f for both compilers. No source port is required.

The primary-program comparison excludes the five test programs and two unchanged precompiled ARC22 inputs. The libraries, u256 and oracle_types, emit no standalone program bytecode.

Primary program Before bytes After bytes Change
shield_swap.aleo 1,480,499 1,390,305 -90,194 (-6.09%)
shield_swap_freezelist.aleo 5,727 5,727 0
shield_swap_lp_router.aleo 21,344 21,344 0
shield_swap_multisig_core.aleo 39,324 39,324 0
shield_swap_pricing_terms.aleo 9,140 9,140 0
shield_swap_rebalance_router.aleo 44,851 44,851 0
shield_swap_router.aleo 35,507 35,507 0
Total 1,636,392 1,546,198 -90,194 (-5.51%)

Only shield_swap.aleo changes. Its line count changes from 36,903 to 35,340 (-1,563). The other six primary programs are byte-identical. Total primary-program lines change from 40,494 to 38,931.

Upgrade compatibility: shield_swap

The candidate bytecode is not a valid upgrade from the baseline bytecode built from the same pinned AMM source. The interface, closure, and constructor checks pass. The record-output register check fails. snarkVM requires these registers to stay unchanged for upgrades at V10 and later, including V23.

Function Record type Baseline output register Candidate output register
mint PositionNFT r1242 r972
mint MintComplianceRecord r1241 r971
rebalance_position PositionNFT r840 r660
rebalance_position MintComplianceRecord r839 r659
collect PositionNFT r826 r646

Do not use this size reduction as evidence of upgrade compatibility. To upgrade from this baseline, the new bytecode must preserve the existing record-output registers. The custom constructor also requires multisig approval for the exact new checksum and next edition.

At the observed mainnet height of 23,392,293, the endpoint reports shield_swap.aleo at edition 3, deployed at block 22,245,833 in transaction at1ts87l4c708nffeyd8l75cgje69trrmzyr8vnhe5ddeeurccj2grs5076w2. Its record-output registers match the baseline column above. The candidate fails the same record-register check against this deployed edition. A separate constructor mismatch exists in both baseline and candidate builds: the pinned source uses a different initial deployer address from edition 3. The baseline passes the record-register check but fails the constructor check. The candidate fails both. V23 does not remove either upgrade restriction.

AMM test-program outputs
Test program Before bytes After bytes Change
test_token_a.aleo 5,718 5,718 0
test_token_b.aleo 5,718 5,718 0
test_token_c.aleo 5,719 5,719 0
test_token_d.aleo 5,719 5,719 0
test_oracle_consumer.aleo 139,832 139,871 +39
Total 162,706 162,745 +39 (+0.024%)

The oracle consumer increases by 39 bytes, while its line count changes from 3,930 to 3,924. The four token programs are byte-identical. Total test-program lines change from 4,698 to 4,692 (-6).

@mohammadfawaz
mohammadfawaz force-pushed the mohammadfawaz/ternary_ops branch from d971f26 to 7dcbd63 Compare April 18, 2026 20:28
@mohammadfawaz mohammadfawaz self-assigned this Apr 20, 2026
@mohammadfawaz mohammadfawaz added dependencies Pull requests that update a dependency file, 🧱 Core Compiler Anything related to the core compiler including parsing, analysis, transforms, codegen, etc. 🚀 feature A new feature. labels Apr 20, 2026
Switch snarkVM to the `mohammadfawaz/complex_ternary` branch (PR #3222),
which extends the `ternary` instruction to accept literal, array, and
plaintext struct operands in addition to registers.

The flattening pass is updated to preserve aggregate ternaries over
arrays, plaintext structs, and primitives / identifiers / literals rather
than decomposing them field-by-field. Records are still decomposed
per-field because their ciphertext components cannot appear directly as
`ternary` operands. The pass docstring is updated to reflect the new
behaviour in both transition and finalize contexts.

Also bumps `rand` and `rand_chacha` to `0.10` to match snarkVM, with the
corresponding CLI call-site adjustments.

New compiler and execution tests exercise ternaries over structs, nested
structs, arrays, arrays of structs, records, primitives, and the
`identifier` type, in both transition and finalize contexts.
@mohammadfawaz
mohammadfawaz force-pushed the mohammadfawaz/ternary_ops branch from 7dcbd63 to 1e04f77 Compare May 29, 2026 22:30
Merge current master and use the rebased snarkVM ternary branch. Align RocksDB with that dependency. Update the flattening pass for the current type APIs. Update constructor and execution fixtures for the current harness and consensus V23. Regenerate compiler and execution expectations.
@mohammadfawaz mohammadfawaz changed the title feat(passes): leverage snarkVM aggregate ternary opcodes feat(passes): preserve aggregate ternary instructions Nov 2, 2026

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

🧱 Core Compiler Anything related to the core compiler including parsing, analysis, transforms, codegen, etc. dependencies Pull requests that update a dependency file, 🚀 feature A new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant