This is an archive of the discontinued LLVM Phabricator instance.

[AArch64TTI] AArch64 supports NT vector stores through STNP.
ClosedPublic

Authored by fhahn on Jan 21 2020, 7:40 PM.

Details

Summary

This patch adds a custom implementation of isLegalNTStore to AArch64TTI
that supports vector types that can be directly stored by STNP. Note
that the implementation may not catch all valid cases (e.g. because the
vector is a multiple of 256 and could be broken down to multiple valid 256 bit
stores), but it is good enough for LV to vectorize loops with NT stores,
as LV only passes in a vector with 2 elements to check. LV seems to also
be the only user of isLegalNTStore.

We should also do the same for NT loads, but before that we need to
ensure that we properly lower LDNP of vectors, similar to D72919.

Diff Detail

Event Timeline

fhahn created this revision.Jan 21 2020, 7:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 21 2020, 7:40 PM

Unit tests: unknown.

clang-tidy: unknown.

clang-format: unknown.

Build artifacts: diff.json, console-log.txt

fhahn updated this revision to Diff 239490.Jan 21 2020, 9:52 PM

Add missing bits of diff.

Unit tests: unknown.

clang-tidy: unknown.

clang-format: pass.

Build artifacts: diff.json, clang-format.patch, CMakeCache.txt, console-log.txt

dmgreen added inline comments.Jan 22 2020, 5:56 AM
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
185

Floats too, at least for Neon types?

188–189

Are these because the vectorizer will run this with:

// Arbitrarily try a vector of 2 elements.
Type *VecTy = VectorType::get(T, /*NumElements=*/2);
...
if (!TTI->isLegalNTStore(VecTy, *Alignment))

And decides at that point if it is legal or not? Without knowing real vector widths.

191

isLegalMaskedStore->isLegalNTStore

It seems that the base version of isLegalNTStore just checks:

// By default, assume nontemporal memory stores are available for stores
// that are aligned and have a size that is a power of 2.
unsigned DataSize = DL.getTypeStoreSize(DataType);
return Alignment >= DataSize && isPowerOf2_32(DataSize);

I'm guessing that it is the alignment that is causing problems for these larger vectors?

fhahn updated this revision to Diff 239632.Jan 22 2020, 9:49 AM

Generalize checks, add additional tests.

fhahn marked 2 inline comments as done.Jan 22 2020, 10:39 AM
fhahn added inline comments.
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
188–189

I've generalised the checks, but yes, that is the reason. I think what LV does is relatively reasonable. LV should only create power of 2 vectors and if <2 x ty> is legal, any vector it creates can be broken down to <2 x ty> I think.

191

I don't think the default implementation is relevant for AArch64. I could not find anything in ArmARM that would indicate any alignment requirements on STNP/LDNP addresses. I think we should probably handle non-vector types here similar to vector types, but probably best done as follow-on change (also, I don't think there are any non-vector users currently in tree)

dmgreen accepted this revision.Jan 22 2020, 2:44 PM

OK. I think this is good. I honestly wouldn't object to just returning isPowerOf2(DataTypeSize), but the code you have looks better. The real answer, as far as I can tell is any scalar/vector that is a multiple of 64. Like you said with any alignment.

But the vectorizer calls this with kind of silly values, so we have to do the best we can. Anything else will just be turned into a normal store anyway, which isn't particularly bad and I don't think should block vectorization (especially if we start with a store size that would not end up being be non-temporal anyway!)

LGTM. Maybe add a comment about how the vectorizer will call the function with a vector width of 2 (in case that changed in the future, we can see where this logic came from).

This revision is now accepted and ready to land.Jan 22 2020, 2:44 PM
fhahn added a comment.Jan 22 2020, 4:57 PM

Thanks, I'll add a note about the LV use before committing.

This revision was automatically updated to reflect the committed changes.