Skip to content

bug(noir): Noir struggles to remove dead code created by context objects when a loop is injected  #4979

@Maddiaa0

Description

@Maddiaa0

repro: md/repro-brillig-explosion

When refactoring the public_state.write method to write one field at a time, (rather than writing an entire array of fields at once) I have come across an interesting loop unrolling issue in brillig gen. I've spent some time diving into the brillig code to work out where the issue is.

I changed
let fields = T::serialize(value);
storage_write(self.storage_slot, fields);

to

let fields = T::serialize(value);
for i in 0..fields.len() {
    storage_write(self.storage_slot + i, fields[i]);
}

And saw the number of brillig opcodes jump from ~10 to 2000.
I originally thought it was some generic issue, but it turns out that if you just replace the code with

for i in 0..1 {
    println(i);
}

Where the loop should only run once, then the same blow up to 2000 opcodes exists.
[https://github.com/AztecProtocol/aztec-packages/blob/58da8815a68642ea78980de2a6d0f[…]df7/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr
](

)

I have done it on this branch, just run

directory: /noir-projects/noir-contracts
command: nargo compile --package avm_test_contract --silence-warnings

and see the brillig output (show_brillig is hardcoded to true)
To see what the output previously was you can comment the loop, and uncomment storage_writes to see the number of contraints go back to normal

https://github.com/AztecProtocol/aztec-packages/blob/58da8815a68642ea78980de2a6d0f1bbbed88df7/noir-projects/aztec-nr/aztec/src/state_vars/public_state.nr
for i in 0..1 {

From the debugging that I have done, I think the inclusion of the loop breaks noir's dead code elimination somewhat. Where the Option::none() in the context object are not removed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-avmComponent: AVM related tickets (aka public VM)C-noirComponent: Noir/NargoT-bugType: Bug. Something is broken.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions