This is an archive of the discontinued LLVM Phabricator instance.

[SVE] Fix isLoadInvariantInLoop for scalable vectors
ClosedPublic

Authored by david-arm on Sep 7 2020, 1:53 AM.

Details

Summary

I've amended the isLoadInvariantInLoop function to bail out for
scalable vectors for now since the invariant.start intrinsic is only
ever generated by the clang frontend for thread locals or struct
and class constructors, neither of which support sizeless types.
In addition, the intrinsic itself does not currently support the
concept of a scaled size, which makes it impossible to compare
the sizes of different scalable objects, e.g. <vscale x 32 x i8>
and <vscale x 16 x i8>.

Added new tests here:

Transforms/LICM/AArch64/sve-load-hoist.ll

Diff Detail

Event Timeline

david-arm created this revision.Sep 7 2020, 1:53 AM
Herald added a reviewer: efriedma. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
david-arm requested review of this revision.Sep 7 2020, 1:53 AM
david-arm updated this revision to Diff 290427.Sep 8 2020, 1:30 AM
david-arm edited the summary of this revision. (Show Details)
  • Added check for -1 argument passed to invariant.start intrinsic.
  • Added comments explaining reasons for bailing out in isLoadInvariantInLoop.
sdesmalen added inline comments.Sep 9 2020, 5:20 AM
llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
818 ↗(On Diff #290427)

It is probably important for isLegalAddressingMode to know whether the Offset and/or Scale is a multiple of vscale, so it makes sense to encode that in a TypeSize. I would prefer to either keep the warning or make isLegalAddressingMode accept a TypeSize, instead of explicitly removing the 'vscale' information here and replacing the warning with a TODO.

llvm/lib/Transforms/Scalar/LICM.cpp
954

This change seems untested, as none of your tests has a llvm.invariant.start intrinsic (and so there is no code-path tested that would otherwise return true)

988

This may be better addressed in a separate patch, because this is unrelated to SVE or scalable vectors.

Just to confirm what's at fault here. If the number of invariant bits of an object is unknown, it is wrong to assume that the load is invariant by checking LocSizeInBits.getFixedSize() <= InvariantSizeInBits. Here InvariantSizeInBits would be (unsigned) -1, so this is always true. Where in fact, we expect it to evaluate to false.

990

It seems odd to assert that here. This is probably better added as a check to the IR Verifier pass, and here bail out with:

if (InvariantSize < 0)
  continue;
llvm/test/Transforms/LICM/AArch64/sve-load-hoist.ll
2

These tests don't test anything from the patch, as they already pass with current master.

david-arm updated this revision to Diff 290920.Sep 10 2020, 3:13 AM
david-arm marked 5 inline comments as done.
david-arm edited the summary of this revision. (Show Details)
  • Added more test cases that fail without my patch and pass with.
  • Removed the assert in isLoadInvariantInLoop.
  • Added Verifier checks for invariant.start intrinsic parameter.
david-arm added inline comments.Sep 10 2020, 3:13 AM
llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
818 ↗(On Diff #290427)

OK I'll make the change to isLegalAddressingMode in a separate patch to support compound BaseOffsets that are true polynomials, i.e. pass a BaseOffset and a ScaledBaseOffset to isLegalAddressingMode.

llvm/lib/Transforms/Scalar/LICM.cpp
988

So it is related to SVE in a way, because if the C++ frontend in clang ever did decide to support sizeless types in structs, classes or thread locals (SVE ACLE types are sizeless) then this value may actually be -1 (unless the definition of the intrinsic is changed to formally deal with scalable types).

Yes, the problem is that in the code below we are potentially casting -1 (which can occur for any incomplete type in clang) to unsigned and therefore always hoisting the load out, which is wrong. I think if we expect to never hit the -1 case here then there should probably be an assert instead.

sdesmalen added inline comments.Sep 14 2020, 3:39 AM
llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
818 ↗(On Diff #290427)

I don't think it needs to be support compound BaseOffsets that are true polynomials. Because scalable vectors are not allowed as members of structs, we can't construct a gep that leads to a compound offset with both unscaled and vscale'd parts.

sdesmalen added inline comments.Sep 14 2020, 6:02 AM
llvm/test/Transforms/LICM/AArch64/sve-load-hoist.ll
12

If you want to test the new condition you added:

if (LocSizeInBits.isScalable())
return false;

then you need to use a value >= 0 for llvm.invariant.start, as otherwise this test will also pass without your change.

30

No code changes in this patch are tested with this test as it doesn't use llvm.invariant.start. I think you should remove these tests from the patch, as I suspect they produce warnings and thus deserve fixing separately.

david-arm updated this revision to Diff 291555.Sep 14 2020, 6:18 AM
  • Removed tests for hoisting/not hoisting scalable vectors that do not have an invariant.start intrinsic.
  • Changed the one remaining test in sve-hoist.ll to use a parameter of 16 instead of -1.
david-arm marked an inline comment as done.Sep 14 2020, 6:24 AM
david-arm added inline comments.
llvm/test/Transforms/LICM/AArch64/sve-load-hoist.ll
12

Without my patch the test fails in the same way for both parameters of -1 and 16 because we hoist in both cases. With my patch the test passes in the same way because we bail out at the same point. However, I think I understand why you prefer using 16.

sdesmalen accepted this revision.Sep 14 2020, 7:46 AM

LGTM!

nit: I don't know if Clang ever really generates a llvm.invariant.start with -1 size in practice, but if it does, you may want to land this patch as two separate patches, one patch that prevents hoisting when size = -1 and another to stop the hoisting for scalable vectors.

This revision is now accepted and ready to land.Sep 14 2020, 7:46 AM
This revision was automatically updated to reflect the committed changes.
david-arm marked an inline comment as done.