-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[SCEV] Fold ((-1 * C1) * D / C1) -> -1 * D. #157555
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3217,15 +3217,19 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, | |
| } | ||
|
|
||
| // Try to fold (C1 * D /u C2) -> C1/C2 * D, if C1 and C2 are powers-of-2, | ||
| // D is a multiple of C2, and C1 is a multiple of C1. | ||
| // D is a multiple of C2, and C1 is a multiple of C2. | ||
| const SCEV *D; | ||
| APInt C1V = LHSC->getAPInt(); | ||
| // If C1 is negative, try (-1 * abs(C1)) instead. | ||
| if (C1V.isNegative() && !C1V.isMinSignedValue()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the INT_MIN check here needed? Isn't abs() just a no-op for that?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah it's a no-op, we would end up with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll leave it as-is for now, when this gets generalized to non-constants we can adjust it |
||
| C1V = C1V.abs(); | ||
| const SCEVConstant *C2; | ||
| const APInt &LHSV = LHSC->getAPInt(); | ||
| if (LHSV.isPowerOf2() && | ||
| if (C1V.isPowerOf2() && | ||
| match(Ops[1], m_scev_UDiv(m_SCEV(D), m_SCEVConstant(C2))) && | ||
| C2->getAPInt().isPowerOf2() && LHSV.uge(C2->getAPInt()) && | ||
| LHSV.logBase2() <= getMinTrailingZeros(D)) { | ||
| return getMulExpr(getUDivExpr(LHSC, C2), D); | ||
| C2->getAPInt().isPowerOf2() && C1V.uge(C2->getAPInt()) && | ||
| C1V.logBase2() <= getMinTrailingZeros(D)) { | ||
| const SCEV *NewMul = getMulExpr(getUDivExpr(getConstant(C1V), C2), D); | ||
| return C1V == LHSC->getAPInt() ? NewMul : getNegativeSCEV(NewMul); | ||
| } | ||
| } | ||
| } | ||
|
|
||
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.
Adjust the comment to something like:
(C1 * D /u C2) == -1 * -C1 * D /u C2 when C1 != INT_MIN
Though maybe that's not quite right because that equality still holds (just not in a useful way) when C1 is INT_MIN.
Basically, we need something here with more of indication of why it's correct.
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.
Updated, thanks!