-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[APInt] Fix APInt constructions where value does not fit bitwidth (NFCI) #80309
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
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
95f49c5
to
c7b2f06
Compare
Before I spend time tracking down all assertion failures, I'd like to have some feedback on the general change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the plan to set implicitTrunc in so many places or is this part of tracking down all the regressions?
llvm/include/llvm/ADT/APInt.h
Outdated
: BitWidth(numBits) { | ||
if (!implicitTrunc) { | ||
if (BitWidth == 0) { | ||
assert(val == 0 && "Value must be zero for 0-bit APInt"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth putting the if-else conditions inside the assert directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the conditions end up fairly complex, I figured it's better to have if/else. If assert() expands to nothing, they'll get optimized away.
Apart from a couple marked TODO, most of them are here to stay. E.g. that bit of code in ConstantFolding has "sext or trunc" semantics, so doing something like "isSigned = true, implicitTrunc = true" there makes sense. Some of them could be avoided, but it's not really clear that it's worthwhile/desirable. E.g. the one in FuzzMutate/OpDescriptor really doesn't really care about the actual value, so doing a truncation is as good as anything else. |
As a side note, it seems like not having the implicit truncation also improves compile-time: http://llvm-compile-time-tracker.com/compare.php?from=fd191378dce6b20c100da716f94130af2593df37&to=df515f3e94d5f5d10ecddfb60181d8866817cc27&stat=instructions:u |
@nikic Thanks for working on this! |
This transform is working on signed integer, so this is the logically correct API. Split off from #80309.
This enables the assertion introduced in #106524, which checks that the value passed to the APInt constructor is indeed a valid N-bit signed or unsigned integer. Places that previously violated the assertion were updated in advance, e.g. in #80309. It is possible to opt-out of the check and restore the previous behavior by setting implicitTrunc=true.
This enables the assertion introduced in llvm#106524, which checks that the value passed to the constructor is indeed a valid N-bit signed or unsigned integer. Places that previously violated the assertion were updated in advance, e.g. in llvm#80309. It is possible to opt-out of the check and restore the previous behavior by setting implicitTrunc=true. ----- The buildbot failures from the previous attempt should be fixed by a18dd29 and e2074c6.
This enables the assertion introduced in #106524, which checks that the value passed to the constructor is indeed a valid N-bit signed or unsigned integer. Places that previously violated the assertion were updated in advance, e.g. in #80309. It is possible to opt-out of the check and restore the previous behavior by setting implicitTrunc=true. ----- The buildbot failures from the previous attempt should be fixed by a18dd29 and e2074c6.
This enables the assertion introduced in llvm#106524, which checks that the value passed to the constructor is indeed a valid N-bit signed or unsigned integer. Places that previously violated the assertion were updated in advance, e.g. in llvm#80309. It is possible to opt-out of the check and restore the previous behavior by setting implicitTrunc=true. ----- The buildbot failures from the previous attempt should be fixed by a18dd29 and e2074c6.
This enables the assertion introduced in llvm#106524, which checks that the value passed to the constructor is indeed a valid N-bit signed or unsigned integer. Places that previously violated the assertion were updated in advance, e.g. in llvm#80309. It is possible to opt-out of the check and restore the previous behavior by setting implicitTrunc=true. ----- The buildbot failures from the previous attempt should be fixed by a18dd29 and e2074c6.
Split out from llvm/llvm-project#80309.
Split out from llvm/llvm-project#80309.
Split out from llvm/llvm-project#80309.
Split out from llvm/llvm-project#80309.
Split out from llvm/llvm-project#80309.
This transform is working on signed integer, so this is the logically correct API. Split off from llvm/llvm-project#80309.
Split off from llvm/llvm-project#80309.
Split off from llvm/llvm-project#80309.
The -1 constant should be sign extended, not zero extended. Split out from llvm/llvm-project#80309.
We were missing the signed flag on the negative value, so the range was incorrectly interpreted for integers larger than 64-bit. Split out from llvm/llvm-project#80309.
Split out from llvm/llvm-project#80309 to avoid assertion failures in the future.
Split out from llvm/llvm-project#80309 to avoid assertion failures in the future.
This handles the edge case where BitWidth is 1 and doing the increment gets a value that's not valid in that width, while we just want wrap-around. Split out of llvm/llvm-project#80309.
This enables the assertion introduced in llvm/llvm-project#106524, which checks that the value passed to the APInt constructor is indeed a valid N-bit signed or unsigned integer. Places that previously violated the assertion were updated in advance, e.g. in llvm/llvm-project#80309. It is possible to opt-out of the check and restore the previous behavior by setting implicitTrunc=true.
This fixes all the places that hit the new assertion added in #106524 in tests. That is, cases where the value passed to the APInt constructor is not an N-bit signed/unsigned integer, where N is the bit width and signedness is determined by the isSigned flag.
The fixes either set the correct value for isSigned, set the implicitTrunc flag, or perform more calculations inside APInt.
Note that the assertion is currently still disabled by default, so this patch is mostly NFC.