This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Don't store AddRec loop when simplifying multiplication of AddRecs
ClosedPublic

Authored by dmakogon on Jun 19 2023, 2:43 AM.

Details

Summary

When multiplying several AddRecs, we do the following simplification:

{A1,+,A2,+,...,+,An}<L> * {B1,+,B2,+,...,+,Bn}<L> = {x=1 in [ sum y=x..2x [ sum z=max(y-x, y-n)..min(x,n) [choose(x, 2x)*choose(2x-y, x-z)*A_{y-z}*B_z]]],+,...up to x=2n}

This is done iteratively, pair by pair. So if we try to multiply three AddRecs A1, A2, A3, then we'd try to simplify A1 * A2 to A1' and then try to simplify A1' * A3 if A1' is also an AddRec.
The transform is only legal if the loops of the two AddRecs are the same. It is checked in the code, but the loop of one of the AddRecs is stored in a local variable and doesn't get updated when we simplify a pair to a new AddRec.
In the motivating test the new AddRec A1' was created for a different loop and, as the loop variable didn't get updated, the check for different loops passed and the transform worked for two AddRecs from different loops. So it created a wrong SCEV. And it caused LSR to replace an instruction with another one that had the same SCEV as the incorrectly computed one.

Diff Detail

Event Timeline

dmakogon created this revision.Jun 19 2023, 2:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 19 2023, 2:43 AM
dmakogon requested review of this revision.Jun 19 2023, 2:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 19 2023, 2:43 AM
dmakogon edited the summary of this revision. (Show Details)Jun 21 2023, 10:59 PM
dmakogon edited the summary of this revision. (Show Details)Jun 21 2023, 11:04 PM
nikic accepted this revision.Jun 22 2023, 12:04 AM

LGTM

This revision is now accepted and ready to land.Jun 22 2023, 12:04 AM
This revision was landed with ongoing or failed builds.Jun 22 2023, 1:50 AM
This revision was automatically updated to reflect the committed changes.