This is an archive of the discontinued LLVM Phabricator instance.

[SVE][AArch64] Fix TypeSize warning in loop vectorization legality
ClosedPublic

Authored by joechrisellis on Oct 20 2020, 8:41 AM.

Details

Summary

The warning would fire when calling isDereferenceableAndAlignedInLoop
with a scalable load. Calling isDereferenceableAndAlignedInLoop with a
scalable load would result in the use of the now deprecated implicit
cast of TypeSize to uint64_t through the overloaded operator.

This patch fixes this issue by:

  • no longer considering vector loads as candidates in canVectorizeWithIfConvert. This doesn't make sense in the context of identifying scalar loads to vectorize.
  • making use of getFixedSize inside isDereferenceableAndAlignedInLoop -- this removes the dependency on the deprecated interface, and will trigger an assertion error if the function is ever called with a scalable type.

Diff Detail

Event Timeline

joechrisellis created this revision.Oct 20 2020, 8:41 AM
Herald added a project: Restricted Project. · View Herald Transcript
joechrisellis requested review of this revision.Oct 20 2020, 8:41 AM
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
1021

I'd be tempted to make this if (!foo()) continue, so that the "passing" case is in the body of the loop, thus making it straightforward to add or remove conditions from the loop.

Address peterwaller-arm's comments regarding control flow readability

sdesmalen added inline comments.Oct 20 2020, 9:48 AM
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
1021

nit: yet now the diff is bigger, it seems simpler to just add one extra line:

      if (LI && !mustSuppressSpeculation(*LI) &&
+         !LI->getType()->isVectorType() &&
          isDereferenceableAndAlignedInLoop(LI, TheLoop, SE, *DT))
llvm/test/Transforms/LoopVectorize/AArch64/sve-scalable-load-in-loop.ll
4

Can you add a description of what this test is supposed to be testing?

Given that there are no CHECK lines that verify the output of opt, you may as well leave the first call to FileCheck out.

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
1021

On this occasion he was following https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code

Is there an etiquette to minimize size-of-diff?

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
1021

I guess that would be covered by the introduction [0] to the guide. It explicitly says that large scale refactoring isn't wanted, but that if you're changing it anyway then update it. My thinking is that that this sort of small patch it would be legitimate to update the style in the surrounding to follow the guide with respect to the early exit recommendation.

So what do others think on balance: legitimate in this case or not?

[0] https://llvm.org/docs/CodingStandards.html#introduction

david-arm added inline comments.Oct 20 2020, 11:58 PM
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
1021

I understand where you're coming from here @peterwaller-arm and there have been occasions in the past where reviewers have also asked me to redo code to make things a bit clearer and follow a preferred style. I don't think it's wrong to undertake small scale refactoring. I guess it's just in this particular case the early-exit link you posted above gives an example where the if block is very large, i.e. the docs say "This code has several problems if the body of the 'if' is large." In this particular patch the if block is a single line statement, so perhaps it's fine to have a multi-condition if statement?

david-arm added inline comments.Oct 21 2020, 12:03 AM
llvm/test/Transforms/LoopVectorize/AArch64/sve-scalable-load-in-loop.ll
4

There is a CHECK-LABEL line below. but I think if you keep the first FileCheck then it's good to add at least one more CHECK line, perhaps something like:

; CHECK-NOT: vector.body

? I've seen other tests do something similar.

sdesmalen added inline comments.Oct 21 2020, 1:07 AM
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
1021

One of the main benefits of rewriting to a loop to one with early exits is when there are multiple nested conditions, e.g.

for(...) {
  if (auto *X = dyn_cast<something>(....)) 
    if (<some condition>)
      // ...
      if (<some other condition>)
        // ... hand the case
 }

Where it is better to pick those apart to avoid the multiple levels of indentation.

With the coding standard there is some freedom of interpretation, because it doesn't give any quantifications for what a 'large' body or condition is and leaves the trade-off between "size of patch" and "refactoring clarifies the code" up to the developer. That's intentional to avoid people rewriting lots of existing code into canonical form because they need to add one line. In this particular case, because the indentation is just one level and the body of the if-statement has only one statement, I think that balance tips in the favour of the one-line change over the refactoring.

joechrisellis marked 2 inline comments as done.

Revert to single-line if statement, add description to the test, and add an
additional check line.

This revision is now accepted and ready to land.Oct 21 2020, 3:29 AM
This revision was landed with ongoing or failed builds.Oct 26 2020, 10:41 AM
This revision was automatically updated to reflect the committed changes.