This is an archive of the discontinued LLVM Phabricator instance.

[Analysis] Fix getNumberOfParts to return 0 when the answer is unknown
ClosedPublic

Authored by david-arm on Nov 12 2021, 6:57 AM.

Details

Summary

When asking how many parts are required for a scalable vector type
there are occasions when it cannot be computed. For example, <vscale x 1 x i3>
is one such vector for AArch64+SVE because at the moment no matter how we
promote the i3 type we never end up with a legal vector. This means
that getTypeConversion returns TypeScalarizeScalableVector as the
LegalizeKind, and then getTypeLegalizationCost returns an invalid cost.
This then causes BasicTTImpl::getNumberOfParts to dereference an invalid
cost, which triggers an assert. This patch changes getNumberOfParts to
return 0 for such cases, since the definition of getNumberOfParts in
TargetTransformInfo.h states that we can use a return value of 0 to represent
an unknown answer.

Currently, LoopVectorize.cpp is the only place where we need to check for
0 as a return value, because all other instances will not currently
ask for the number of parts for <vscale x 1 x iX> types.

In addition, I have changed the target-independent interface for
getNumberOfParts to return 1 and assume there is a single register
that can fit the type. The loop vectoriser has lots of tests that are
target-independent and they relied upon the 0 value to mean the
answer is known and that we are not scalarising the vector.

I have added tests here that show we correctly return an invalid cost
for VF=vscale x 1 when the loop contains unusual types such as i7:

Transforms/LoopVectorize/AArch64/sve-inductions-unusual-types.ll

Diff Detail

Event Timeline

david-arm created this revision.Nov 12 2021, 6:57 AM
david-arm requested review of this revision.Nov 12 2021, 6:57 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 12 2021, 6:57 AM

An alternative solution to changing llvm/include/llvm/Analysis/TargetTransformInfoImpl.h would be to fix LoopVectorize.cpp so that it never calls getNumberOfParts unless we have defined a target. For example, we could just set TypeNotScalarized to be true always when there is no target specified. I wasn't sure which solution was best so I pushed this patch up for now!

When asking how many parts are required for a scalable vector type there are occasions when it cannot be computed. For example, <vscale x 1 x i3> is one such vector for AArch64+SVE because no matter how we promote the i3 type we never end up with a legal vector.

Not sure I agree with the premise here. Legalizing to <vscale x 2 x i64> should be a viable strategy. I mean, under most circumstances I wouldn't expect the vectorizer to construct vscale x 1 vectors, but we've already done a significant amount of work to allow lowering such vectors.

When asking how many parts are required for a scalable vector type there are occasions when it cannot be computed. For example, <vscale x 1 x i3> is one such vector for AArch64+SVE because no matter how we promote the i3 type we never end up with a legal vector.

Not sure I agree with the premise here. Legalizing to <vscale x 2 x i64> should be a viable strategy. I mean, under most circumstances I wouldn't expect the vectorizer to construct vscale x 1 vectors, but we've already done a significant amount of work to allow lowering such vectors.

Hi @efriedma, you're right that at some point we might be able to support this should we care about <vscale x 1 x iX> types. However, this patch is more about fixing up a genuine hole in how we use getNumberOfParts to determine if something has been vectorised or not. At the moment, for <vscale x 1 x i3> types we do crash because getNumberOfParts dereferences an invalid cost so I'd like to fix this hole first as a priority to at least stabilise the vectoriser in the short term. Perhaps I can update the commit message to be less misleading?

Given that TargetLoweringBase::getTypeLegalizationCost() can currently fail, I guess this patch makes sense. Long-term, I'm not sure we want it to fail in cases like this, but we don't need to deal with that right now.

The commit message should probably mention TypeScalarizeScalableVector somewhere.

sdesmalen accepted this revision.Nov 16 2021, 6:24 AM

Seems like a sensible fix to me. Thanks!

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
7432

Not something introduced by your patch, but the name VectorTy seems wrong here :)

This revision is now accepted and ready to land.Nov 16 2021, 6:24 AM
david-arm edited the summary of this revision. (Show Details)Nov 17 2021, 2:59 AM