fix ub in lower rounding shift right #8173
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is the implementation of lower_rounding_shift_right on main:
Consider
lower_rounding_shift_right(a, (uint8)0)
The term b - 1 becomes 255, and now you have an out-of-range shift,
which causes the simplifier to inject a signed_integer_overflow
intrinsic, and compilation to fail.
This is a little annoying because if b == 0, b_positive is a zero mask,
so the result isn't used anyway (this is also why this change is legal).
In llvm, it's a poison value, not UB, so masking it off works. If the
simplifier were smarter, it might just drop the signed_integer_overflow
intrinsic on detecting that it was being bitwise-and-ed with zero.
But the safest thing to do is not overflow. saturating_add/sub are
typically as cheap as add/sub. 99.9% of the time b is some positive
constant anyway, so it's going to get constant-folded.