fix(acir-gen): Do not generate ACIR array opcodes when the length is zero#9195
fix(acir-gen): Do not generate ACIR array opcodes when the length is zero#9195
Conversation
|
Looks like this covers #9193, |
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: bc10d91 | Previous: 9efc476 | Ratio |
|---|---|---|---|
test_report_zkpassport_noir_rsa_ |
2 s |
1 s |
2 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @TomAFrench
Yeah, I agree that this isn't the best solution for this issue but it's relatively light touch so if it unblocks master then I'm happy to merge it as a stopgap. I think the ideal solution on this is to handle this in SSA where I think we can be more aggressive on marking certain instructions as unreachable. |
|
I checked locally that it does unblock #9108 and #9061 I agree it would be nice to make unreachable instruction removal take care of this. As discussed it has a bit of cascading effect at the moment: maybe we could replace variables with defaults that are defined until the next side effect variable, or do it earlier, but then it disrupted flattening. @asterite was looking at it. |
|
Apologies for missing this earlier, but it looks like this PR #9050 also tackles the problem of changing acri-gen's behavior to not do
We should also change the behavior not to do |
|
@jfecher thanks for the pointer to Guillaume's PR, I changed it to work like his by inserting an assertion that the side effect variable is false, and doing it whenever the |
…ng/noir into af/9174-fix-acir-gen-empty-slice
maybe, but we can leave it to the other PR to resolve those differences at least |
Description
Problem*
Resolves #9174
Summary*
Changes
handle_array_operationsin ACIR generation to skip generating opcodes for accessing an array when know that the array/slice has a zero size.Additional Context
The code in question has a global zero sized slice, which it accesses in both branches of an if expression:
The final SSA began like this:
And the generated ACIR:
The program failed with the following error:
So this branch should never have run, but the
MEMopcode fails anyway, because even though it looks at the side effect variable to decide whether to get/set items, it always expected a non-empty array.With the changes in the PR, this is now eliminated:
In the original approach of the PR the elimination only happened on the top branch, where it was obvious that the code would never run, because
v2was constrained to be 0. Then I changed it to happen whenever we know the array/slice is empty, which includes theelsebranch:in ACIR this no longer has memory operations either:
So we call Brillig to calculate the modulo (we can look separately into why the compiler did not eliminate this call), then fail unconditionally.
While the reason for the presence of the Brillig call is still something we can work out, the fix should unblock the PRs that fail due to the difference in ACIR and Brillig.
Documentation*
Check one:
PR Checklist*
cargo fmton default settings.