This is an archive of the discontinued LLVM Phabricator instance.

Adding patch and unittest to generalize ignorable induction casts in the LoopVectorizationLegality analysis.
Changes PlannedPublic

Authored by avery-laird on Oct 26 2021, 8:19 AM.

Details

Summary

This patch assumes that casts of the induction phi, from the same type, can be treated as the induction variable for the purposes of the legality analysis. This helps to make the cost model more accurate in certain cases, particularily with getMemInstScalarizationCost.

Diff Detail

Event Timeline

avery-laird created this revision.Oct 26 2021, 8:19 AM
avery-laird requested review of this revision.Oct 26 2021, 8:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 26 2021, 8:19 AM
bmahjour added inline comments.Oct 26 2021, 10:33 AM
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
524

Isn't the subject cast available in the list returned by getCastInsts()?

528

Checking the source type of the cast to match the phi type seems redundant given that we begin by identifying casts that are users of the phi.

529

The comment in LoopVectorizationLegality.h indicates that this list is supposed to contain casts that are noop (possibly guaranteed by some runtime check). IIUC your use case may not have that guarantee. Looking through the code though, it seems we only use this list in cost-estimation, so perhaps it's fine...but if that's the case we should update the comment.

avery-laird planned changes to this revision.Nov 2 2021, 6:12 PM
  • determine whether getCastInsts() can be modified to have the desired behaviour directly (and implement if so)
  • remove redundant type check
  • if necessary, update comment in LoopVectorizationLegality.h to reflect changes
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
524

right now it is not, and that is the main issue. Ideally, getCastInsts() would return these types of casts. I'm currently looking into this further to see if there is a way to instead modify getCastInsts(). One issue with this, as you identified, is that getCastInsts() has stricter guarantees than required by the cost model.

After investigating further into whether this patch can be merged with getCastInsts(), I think there are some difficulties in doing so.

getCastInsts() looks for a specific pattern that I'm not sure fits this case. For example (from comments in IVDescriptor.cpp), given an IR sequence like this:

%for.body:
   %x = phi i64 [ 0, %ph ], [ %add, %for.body ]
   %casted_phi = and  %x, 2^n-1
   %add = add i64 %casted_phi, %step

The cast returned by getCastInsts() will be %casted_phi. The search is done by looking at the operands of %add, in this case finding %casted_phi, and testing whether PSE.getSCEV(%x) is equal to PSE.getSCEV(%casted_phi) under a predicate. Three differences are:

  1. All instructions in the def-use chain must be binary, but sext for example is unary
  2. Instructions must update the incoming value of the phi node to be considered (in this case through %add's use of %casted_phi), but this patch should include instructions that don't update the induction Phi
  3. Instructions need to be of the same type, but this patch should include instructions that may be casts from one type to another

In order to modify getCastInsts() to return the desired casts, at least these three things need to be changed. Additionally, by only changing InductionCastsToIgnore, just the cost model is affected, but getCastInsts() also directly affects code generation.

It seems the goal of getCastInsts() is generally different from what this patch is trying to do, but I am very interested in any feedback! Depending on that, I will update the patch with steps (2) and (3) identified in the plan.