-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: add u128 overflow checks after DIE #7587
base: master
Are you sure you want to change the base?
Conversation
Seems like we could have this easily reoccur in some cases if we were to add more passes in future which would result in more u128 ops being revealed as unused in later passes. 🤔 |
I also checked what happened with signed integers: it always fails with overflow regardless of ACIR and brillig, because the checks are inserted during SSA. One way to solve this particular case is to always check for u128 overflow in SSA, even for brillig. However, for other unsigned types it will still be different (no overflow on unused expressions). So maybe we need to answer this question first: do we want overflows for unused expressions or not? |
Hmm, I'd be open to always performing overflow checks for unused expressions. It'll simplify us not having to jump through hoops to ensure that we never output overflow checks for these operations and I can imagine situations where people expect overflow checks on some arithmetic which they don't use of the result of to constrain a certain result. e.g. // Check that sum fits in a u8.
let _: u8 = x + y; We would potentially take a hit on larger circuit sizes but then it's up to users to not add code to their circuit if they don't want it there. |
Would that require changes to the brillig vm to not check for overflows anymore? |
I'm not sure I follow, how would this affect the brillig VM? |
If we always want to give an error on overflow then we must add those checks, which will end up being some That said, I think right now the checks are deferred to Brillig for performance reasons, so moving those checks back to SSA might introduce some undesired regressions. |
I'm really not seeing where changes to brillig are coming in. If I want to add two u32s together then we have the SSA
Now let's say it's u128s, we now have two different SSAs depending on the runtime:
We know that in ACIR between the standard overflow check and the extra checks injected by Based on this I really don't see how changing how the DIE pass treats unused arithmetic instructions affects whether the brillig VM needs to do overflow checks. |
Ah, this is what I was missing. I thought we'd add the checks in SSA, then DIE wouldn't remove those instructions, but in the end not removing the arithmetic operations that could overflow is the same, and simpler. |
Description
Problem
Resolves #7555
Summary
The compiler generally doesn't issue overflow errors for expressions that end up being unused. The overflow checks for u128 were added before the first DIE pass and contain some
div
andconstrain
instructions that DIE won't remove. Adding these checks after the first DIE fixes the issue as the multiplications are removed by DIE so no checks are added.Additional Context
Documentation
Check one:
PR Checklist
cargo fmt
on default settings.