There are several unhandled edge cases in BasicAA's GetLinearExpression method. This changes fixes outstanding issues, including zext / sext of a constant with the sign bit set, and the refusal to decompose zexts or sexts of wrapping arithmetic.
Details
Diff Detail
Event Timeline
Hi @hfinkel - I've made the fixes you suggested and have added a couple more comments. Thanks -
Nick
Sorry I dropped the ball on this - could you commit it for me as I still
don't have commit access? Thanks -
Nick
Some drop-by-comments inline in case you find them useful. I see this patch has been LGTM'ed so feel free to ignore. :)
lib/Analysis/BasicAliasAnalysis.cpp | ||
---|---|---|
286 | I'm not sure I understand the comment -- this clause looks like it is implementing sext(sext(X,a),b) == sext(X, a + b). | |
291 | Why is the .zextOrSelf(OldWidth) or the .trunc(SmallWidth) needed? Isn't OldWidth always equal to SmallWidth? | |
945 | Do you mean i3? Additions in i8 are modulo 256. | |
949 | Minor: APIntOps::umin may be clearer here. |
No, that's not how things work. All comments need to be addressed. Pre- or post-commit.
In any case, this patch needs to be rebased because it no longer applies cleanly to trunk.
[BasicAA] Fix zext & sext handling
There are several unhandled edge cases in BasicAA's GetLinearExpression method. This changes fixes outstanding issues, including zext / sext of a constant with the sign bit set, and the refusal to decompose zexts or sexts of wrapping arithmetic.
@sanjoy - thanks for the review; bugs in this class are rather hard to track down as they only really manifest themselves in later optimisations, so more eyes are definitely appreciated :). I've replied to all your comments in-line - let me know if anything's not clear.
Nick
lib/Analysis/BasicAliasAnalysis.cpp | ||
---|---|---|
286 | My latest commit adds more comments to make this clearer - does that explain it well enough? | |
291 | This method can call itself recursively, and so the operator width reduces as we look through zexts + sexts, but the offset always stays at the initial width. | |
945 | You're right - and I've added several unit tests prefixed "constantOffsetHeuristic_" to q.bad.ll to explore this behaviour (and to verify that I'm picking the right scales to multiply by in the heuristic). | |
949 | Thanks - code reviews are one of the best ways to discover new utility functions in the codebase :) |
lib/Analysis/BasicAliasAnalysis.cpp | ||
---|---|---|
260 | Note that currently in the LangRef, shl nsw X, Y is not the same as mul nsw X (1 << Y), the LangRef has a bug in this regard. David has an out of tree patch to fix this http://reviews.llvm.org/D8890 but meanwhile you might want to not propagate nuw and nsw for shifts. | |
288 | Very minor, but I think it will be clearer if you just add an annotation to each branch of the if statement: if (is<SEXtInst>(V) && ZExtBits == 0) { // sext(sext(A)) == sext(A) etc. instead of a comprehensive meta comment. |
Hi @sanjoy - I've revised the patch to incorporate your suggestions. Is it OK now? Thanks -
Nick
lib/Analysis/BasicAliasAnalysis.cpp | ||
---|---|---|
260 | That's interesting - I've added an early escape for the Shl that sets NSW & NUW to false in the latest version of this patch so they won't be propagated. | |
288 | I've changed this in my latest revision of this patch. |
nsw -> NSW, nuw -> NUW as per the coding convention.