Skip to content

fix: signed division by -1 can overflow#9976

Merged
asterite merged 17 commits intomasterfrom
ab/signed-division-overflow
Sep 26, 2025
Merged

fix: signed division by -1 can overflow#9976
asterite merged 17 commits intomasterfrom
ab/signed-division-overflow

Conversation

@asterite
Copy link
Collaborator

@asterite asterite commented Sep 24, 2025

Description

Problem

Resolves #9904
Resolves #9971
Resolves #9975
Resolves #10008

Summary

Handles the fact that i8::min / -1 can overflow in all scenarios (comptime interpreter, SSA interpreter, when doing SSA simplification, etc.)

Then there was a related bug in ACIR where for checking this we didn't use the predicate.

Additional Context

I wanted to fix this now because I didn't know if this was related to constant_folding (it partially is) and without this fix it's hard to tell if bugs I find in constant_folding are just a duplicate of one of these issues.

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.

@asterite asterite marked this pull request as ready for review September 24, 2025 14:40
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.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Execution Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 4b2fe87 Previous: 075a31b Ratio
rollup-checkpoint-merge 0.004 s 0.003 s 1.33

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

CC: @TomAFrench

@asterite asterite requested a review from a team September 24, 2025 15:27
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.

⚠️ 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: 13b46dc Previous: 075a31b Ratio
test_report_zkpassport_noir_rsa_ 3 s 2 s 1.50

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

CC: @TomAFrench

Copy link
Contributor

@vezenovm vezenovm left a comment

Choose a reason for hiding this comment

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

Looks good. Before we merge can you check if we solve this too #10008

@asterite
Copy link
Collaborator Author

Looks good. Before we merge can you check if we solve this too #10008

Yes, it solves that too.

Should I add a regression test for it? I'm not sure because maybe in the end it's a duplicate of some of the other issues...

@vezenovm
Copy link
Contributor

Should I add a regression test for it? I'm not sure because maybe in the end it's a duplicate of some of the other issues...

That test has a dynamic divisor. So if you see a test with a dynamic divisor no need, but otherwise doesn't hurt.

@asterite asterite enabled auto-merge September 26, 2025 15:18
@asterite asterite added this pull request to the merge queue Sep 26, 2025
Merged via the queue into master with commit 8ca4af7 Sep 26, 2025
128 checks passed
@asterite asterite deleted the ab/signed-division-overflow branch September 26, 2025 16:03
AztecBot added a commit to AztecProtocol/aztec-packages that referenced this pull request Oct 8, 2025
Automated pull of nightly from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
chore: Remove unnecessary allocation in `expr_with` (noir-lang/noir#10103)
chore(ACIR): inline `maybe_eq_predicate` (noir-lang/noir#10095)
chore: use `u64` over `Field` in template program (noir-lang/noir#10096)
chore: disallow slice arguments to blackbox functions (noir-lang/noir#10090)
chore(brillig_vm): Separate fuzzing module (noir-lang/noir#10091)
chore: ConstrainNotEqual requires acir predicate (noir-lang/noir#10062)
chore: bump version of bb used in tests (noir-lang/noir#10093)
chore: wrapping arithmetic tests (noir-lang/noir#9714)
chore(brillig_vm): Foreign call module and test re-org (noir-lang/noir#10089)
chore: add extra constraint folding pass (noir-lang/noir#9766)
chore: refactor brillig_blocks (noir-lang/noir#10088)
chore: add regression test for #9986 (noir-lang/noir#10087)
chore: Release Noir(1.0.0-beta.14) (noir-lang/noir#9942)
fix(tag_attr): keep whitespace tokens when parsing (noir-lang/noir#9981)
fix: hoist and then deduplicate (noir-lang/noir#10047)
chore: typos and some refactors in `acvm/src/pwg` (noir-lang/noir#10086)
chore: add in hack for `public_dispatch` (noir-lang/noir#10084)
fix(ssa): Avoid going through `i128` when casting signed to `u128` (noir-lang/noir#10045)
chore: avoid zero bits range-checks (noir-lang/noir#10083)
chore: bump external pinned commits (noir-lang/noir#10082)
fix(stdlib): Only compute the garbage `embedded_curve_result` result if we know we will need it (noir-lang/noir#10077)
fix(ssa): Keep defaults for values returned in the databus (noir-lang/noir#10042)
chore: remove unused predicate from mem-op solver (noir-lang/noir#10079)
chore(ACIR): snapshot tests for each instruction (noir-lang/noir#10071)
fix: remove generic length from ECDSA message hash in stdlib (noir-lang/noir#10043)
chore: validate that no jumps to function entry block exist (noir-lang/noir#10076)
feat(brillig): Centralize memory layout policy and reorganize memory regions (noir-lang/noir#9985)
chore(ci): fix permissions about publishing rustdoc (noir-lang/noir#10075)
chore(ACVM): use Vec instead of Hash for memory blocks (noir-lang/noir#10072)
feat(ssa): `constant_folding` with loop (noir-lang/noir#10019)
chore: take truncate into account for bit size (noir-lang/noir#10059)
chore: update check for `u128` overflow in `check_u128_mul_overflow` (noir-lang/noir#9998)
chore: update check for field overflow in `check_u128_mul_overflow` (noir-lang/noir#9968)
chore(ACIR): binary instructions snapshots (noir-lang/noir#10054)
chore(acir): SliceRemove refactor (noir-lang/noir#10058)
fix(fuzzer): Mark DivisionByZero with different types as equivalent (noir-lang/noir#10066)
chore(fuzz): Remove `is_frontend_friendly` from the AST fuzzer (noir-lang/noir#10046)
chore: use new ACIR syntax in docs, and some tests (noir-lang/noir#10057)
fix(ssa): SSA interpreter to use the 2nd arg in `slice_refcount` (noir-lang/noir#10034)
fix(ssa): SSA interpreter to return 0 for `Intrinsic::*RefCount` when constrained (noir-lang/noir#10033)
chore(ssa_fuzzer): fix array get/set  (noir-lang/noir#10031)
fix(acir): Extend slice on dynamic insertion and compilation panic when flattening (noir-lang/noir#10051)
chore(ACIR): extract convert_constrain_error helper (noir-lang/noir#10050)
chore(ACIR): expand signed lt, div and mod in SSA (noir-lang/noir#10036)
chore(ACIR): more consistent syntax and with less noise (noir-lang/noir#10014)
chore(acir): Code gen tests for slice intrinsics (noir-lang/noir#10017)
feat: parse and display SSA databus (noir-lang/noir#9991)
fix(ssa): Handle partially removed `ArrayGet` groups of complex type during OOB checks (noir-lang/noir#10027)
chore(acir): binary operations always have the same operand types (noir-lang/noir#10028)
feat: Add Module::parent and Module::child_modules (noir-lang/noir#10005)
chore: green light for ACVM optimisation (noir-lang/noir#10002)
chore: unit test for brillig solver (greenlight ACVM execution) (noir-lang/noir#9967)
chore(acir): avoid duplication when invoking brillig stdlib call (noir-lang/noir#10025)
chore: Use 8 partitions for rust tests (noir-lang/noir#10026)
chore: green light for ACVM execution audit (noir-lang/noir#9982)
chore: greenlight for ACVM execution (PWG) (noir-lang/noir#9961)
feat: optimize out noop casts on constants (noir-lang/noir#10024)
fix(mem2reg): consider call return aliases (noir-lang/noir#10016)
chore: bump external pinned commits (noir-lang/noir#10022)
fix(parser): enforce left brace after match expression (noir-lang/noir#10018)
chore(acir): Intrinsics and slice_ops modules as well as slice_ops doc comments (noir-lang/noir#10012)
fix: signed division by -1 can overflow (noir-lang/noir#9976)
chore(ci): fix external checks (noir-lang/noir#10009)
chore(ci): add provenance attestations to npm packages (noir-lang/noir#10011)
chore(ACIR): show all expressions as polynomials (noir-lang/noir#10007)
chore: remove unused feature flag (noir-lang/noir#9993)
chore(ci): fix docs breaking JS releases (noir-lang/noir#10010)
chore(ssa_fuzzer): add external coverage registration  (noir-lang/noir#9974)
END_COMMIT_OVERRIDE

Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
github-merge-queue bot pushed a commit to AztecProtocol/aztec-packages that referenced this pull request Oct 8, 2025
Automated pull of nightly from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
chore: Remove unnecessary allocation in `expr_with`
(noir-lang/noir#10103)
chore(ACIR): inline `maybe_eq_predicate`
(noir-lang/noir#10095)
chore: use `u64` over `Field` in template program
(noir-lang/noir#10096)
chore: disallow slice arguments to blackbox functions
(noir-lang/noir#10090)
chore(brillig_vm): Separate fuzzing module
(noir-lang/noir#10091)
chore: ConstrainNotEqual requires acir predicate
(noir-lang/noir#10062)
chore: bump version of bb used in tests
(noir-lang/noir#10093)
chore: wrapping arithmetic tests
(noir-lang/noir#9714)
chore(brillig_vm): Foreign call module and test re-org
(noir-lang/noir#10089)
chore: add extra constraint folding pass
(noir-lang/noir#9766)
chore: refactor brillig_blocks
(noir-lang/noir#10088)
chore: add regression test for #9986
(noir-lang/noir#10087)
chore: Release Noir(1.0.0-beta.14)
(noir-lang/noir#9942)
fix(tag_attr): keep whitespace tokens when parsing
(noir-lang/noir#9981)
fix: hoist and then deduplicate
(noir-lang/noir#10047)
chore: typos and some refactors in `acvm/src/pwg`
(noir-lang/noir#10086)
chore: add in hack for `public_dispatch`
(noir-lang/noir#10084)
fix(ssa): Avoid going through `i128` when casting signed to `u128`
(noir-lang/noir#10045)
chore: avoid zero bits range-checks
(noir-lang/noir#10083)
chore: bump external pinned commits
(noir-lang/noir#10082)
fix(stdlib): Only compute the garbage `embedded_curve_result` result if
we know we will need it (noir-lang/noir#10077)
fix(ssa): Keep defaults for values returned in the databus
(noir-lang/noir#10042)
chore: remove unused predicate from mem-op solver
(noir-lang/noir#10079)
chore(ACIR): snapshot tests for each instruction
(noir-lang/noir#10071)
fix: remove generic length from ECDSA message hash in stdlib
(noir-lang/noir#10043)
chore: validate that no jumps to function entry block exist
(noir-lang/noir#10076)
feat(brillig): Centralize memory layout policy and reorganize memory
regions (noir-lang/noir#9985)
chore(ci): fix permissions about publishing rustdoc
(noir-lang/noir#10075)
chore(ACVM): use Vec instead of Hash for memory blocks
(noir-lang/noir#10072)
feat(ssa): `constant_folding` with loop
(noir-lang/noir#10019)
chore: take truncate into account for bit size
(noir-lang/noir#10059)
chore: update check for `u128` overflow in `check_u128_mul_overflow`
(noir-lang/noir#9998)
chore: update check for field overflow in `check_u128_mul_overflow`
(noir-lang/noir#9968)
chore(ACIR): binary instructions snapshots
(noir-lang/noir#10054)
chore(acir): SliceRemove refactor
(noir-lang/noir#10058)
fix(fuzzer): Mark DivisionByZero with different types as equivalent
(noir-lang/noir#10066)
chore(fuzz): Remove `is_frontend_friendly` from the AST fuzzer
(noir-lang/noir#10046)
chore: use new ACIR syntax in docs, and some tests
(noir-lang/noir#10057)
fix(ssa): SSA interpreter to use the 2nd arg in `slice_refcount`
(noir-lang/noir#10034)
fix(ssa): SSA interpreter to return 0 for `Intrinsic::*RefCount` when
constrained (noir-lang/noir#10033)
chore(ssa_fuzzer): fix array get/set
(noir-lang/noir#10031)
fix(acir): Extend slice on dynamic insertion and compilation panic when
flattening (noir-lang/noir#10051)
chore(ACIR): extract convert_constrain_error helper
(noir-lang/noir#10050)
chore(ACIR): expand signed lt, div and mod in SSA
(noir-lang/noir#10036)
chore(ACIR): more consistent syntax and with less noise
(noir-lang/noir#10014)
chore(acir): Code gen tests for slice intrinsics
(noir-lang/noir#10017)
feat: parse and display SSA databus
(noir-lang/noir#9991)
fix(ssa): Handle partially removed `ArrayGet` groups of complex type
during OOB checks (noir-lang/noir#10027)
chore(acir): binary operations always have the same operand types
(noir-lang/noir#10028)
feat: Add Module::parent and Module::child_modules
(noir-lang/noir#10005)
chore: green light for ACVM optimisation
(noir-lang/noir#10002)
chore: unit test for brillig solver (greenlight ACVM execution)
(noir-lang/noir#9967)
chore(acir): avoid duplication when invoking brillig stdlib call
(noir-lang/noir#10025)
chore: Use 8 partitions for rust tests
(noir-lang/noir#10026)
chore: green light for ACVM execution audit
(noir-lang/noir#9982)
chore: greenlight for ACVM execution (PWG)
(noir-lang/noir#9961)
feat: optimize out noop casts on constants
(noir-lang/noir#10024)
fix(mem2reg): consider call return aliases
(noir-lang/noir#10016)
chore: bump external pinned commits
(noir-lang/noir#10022)
fix(parser): enforce left brace after match expression
(noir-lang/noir#10018)
chore(acir): Intrinsics and slice_ops modules as well as slice_ops doc
comments (noir-lang/noir#10012)
fix: signed division by -1 can overflow
(noir-lang/noir#9976)
chore(ci): fix external checks
(noir-lang/noir#10009)
chore(ci): add provenance attestations to npm packages
(noir-lang/noir#10011)
chore(ACIR): show all expressions as polynomials
(noir-lang/noir#10007)
chore: remove unused feature flag
(noir-lang/noir#9993)
chore(ci): fix docs breaking JS releases
(noir-lang/noir#10010)
chore(ssa_fuzzer): add external coverage registration
(noir-lang/noir#9974)
END_COMMIT_OVERRIDE
mralj pushed a commit to AztecProtocol/aztec-packages that referenced this pull request Oct 13, 2025
Automated pull of nightly from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
chore: Remove unnecessary allocation in `expr_with` (noir-lang/noir#10103)
chore(ACIR): inline `maybe_eq_predicate` (noir-lang/noir#10095)
chore: use `u64` over `Field` in template program (noir-lang/noir#10096)
chore: disallow slice arguments to blackbox functions (noir-lang/noir#10090)
chore(brillig_vm): Separate fuzzing module (noir-lang/noir#10091)
chore: ConstrainNotEqual requires acir predicate (noir-lang/noir#10062)
chore: bump version of bb used in tests (noir-lang/noir#10093)
chore: wrapping arithmetic tests (noir-lang/noir#9714)
chore(brillig_vm): Foreign call module and test re-org (noir-lang/noir#10089)
chore: add extra constraint folding pass (noir-lang/noir#9766)
chore: refactor brillig_blocks (noir-lang/noir#10088)
chore: add regression test for #9986 (noir-lang/noir#10087)
chore: Release Noir(1.0.0-beta.14) (noir-lang/noir#9942)
fix(tag_attr): keep whitespace tokens when parsing (noir-lang/noir#9981)
fix: hoist and then deduplicate (noir-lang/noir#10047)
chore: typos and some refactors in `acvm/src/pwg` (noir-lang/noir#10086)
chore: add in hack for `public_dispatch` (noir-lang/noir#10084)
fix(ssa): Avoid going through `i128` when casting signed to `u128` (noir-lang/noir#10045)
chore: avoid zero bits range-checks (noir-lang/noir#10083)
chore: bump external pinned commits (noir-lang/noir#10082)
fix(stdlib): Only compute the garbage `embedded_curve_result` result if we know we will need it (noir-lang/noir#10077)
fix(ssa): Keep defaults for values returned in the databus (noir-lang/noir#10042)
chore: remove unused predicate from mem-op solver (noir-lang/noir#10079)
chore(ACIR): snapshot tests for each instruction (noir-lang/noir#10071)
fix: remove generic length from ECDSA message hash in stdlib (noir-lang/noir#10043)
chore: validate that no jumps to function entry block exist (noir-lang/noir#10076)
feat(brillig): Centralize memory layout policy and reorganize memory regions (noir-lang/noir#9985)
chore(ci): fix permissions about publishing rustdoc (noir-lang/noir#10075)
chore(ACVM): use Vec instead of Hash for memory blocks (noir-lang/noir#10072)
feat(ssa): `constant_folding` with loop (noir-lang/noir#10019)
chore: take truncate into account for bit size (noir-lang/noir#10059)
chore: update check for `u128` overflow in `check_u128_mul_overflow` (noir-lang/noir#9998)
chore: update check for field overflow in `check_u128_mul_overflow` (noir-lang/noir#9968)
chore(ACIR): binary instructions snapshots (noir-lang/noir#10054)
chore(acir): SliceRemove refactor (noir-lang/noir#10058)
fix(fuzzer): Mark DivisionByZero with different types as equivalent (noir-lang/noir#10066)
chore(fuzz): Remove `is_frontend_friendly` from the AST fuzzer (noir-lang/noir#10046)
chore: use new ACIR syntax in docs, and some tests (noir-lang/noir#10057)
fix(ssa): SSA interpreter to use the 2nd arg in `slice_refcount` (noir-lang/noir#10034)
fix(ssa): SSA interpreter to return 0 for `Intrinsic::*RefCount` when constrained (noir-lang/noir#10033)
chore(ssa_fuzzer): fix array get/set  (noir-lang/noir#10031)
fix(acir): Extend slice on dynamic insertion and compilation panic when flattening (noir-lang/noir#10051)
chore(ACIR): extract convert_constrain_error helper (noir-lang/noir#10050)
chore(ACIR): expand signed lt, div and mod in SSA (noir-lang/noir#10036)
chore(ACIR): more consistent syntax and with less noise (noir-lang/noir#10014)
chore(acir): Code gen tests for slice intrinsics (noir-lang/noir#10017)
feat: parse and display SSA databus (noir-lang/noir#9991)
fix(ssa): Handle partially removed `ArrayGet` groups of complex type during OOB checks (noir-lang/noir#10027)
chore(acir): binary operations always have the same operand types (noir-lang/noir#10028)
feat: Add Module::parent and Module::child_modules (noir-lang/noir#10005)
chore: green light for ACVM optimisation (noir-lang/noir#10002)
chore: unit test for brillig solver (greenlight ACVM execution) (noir-lang/noir#9967)
chore(acir): avoid duplication when invoking brillig stdlib call (noir-lang/noir#10025)
chore: Use 8 partitions for rust tests (noir-lang/noir#10026)
chore: green light for ACVM execution audit (noir-lang/noir#9982)
chore: greenlight for ACVM execution (PWG) (noir-lang/noir#9961)
feat: optimize out noop casts on constants (noir-lang/noir#10024)
fix(mem2reg): consider call return aliases (noir-lang/noir#10016)
chore: bump external pinned commits (noir-lang/noir#10022)
fix(parser): enforce left brace after match expression (noir-lang/noir#10018)
chore(acir): Intrinsics and slice_ops modules as well as slice_ops doc comments (noir-lang/noir#10012)
fix: signed division by -1 can overflow (noir-lang/noir#9976)
chore(ci): fix external checks (noir-lang/noir#10009)
chore(ci): add provenance attestations to npm packages (noir-lang/noir#10011)
chore(ACIR): show all expressions as polynomials (noir-lang/noir#10007)
chore: remove unused feature flag (noir-lang/noir#9993)
chore(ci): fix docs breaking JS releases (noir-lang/noir#10010)
chore(ssa_fuzzer): add external coverage registration  (noir-lang/noir#9974)
END_COMMIT_OVERRIDE

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

None yet

Projects

None yet

3 participants