[PATCH] D66688: [LoopVectorize] Leverage speculation safety to avoid masked.loads
Ayal Zaks via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 8 11:22:40 PDT 2019
Ayal added a comment.
This LGTM, just some minor nits.
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:20
#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/IntrinsicInst.h"
----------------
Ayal wrote:
> nit: lex ordering (the above admittedly sets an unordered example..)
ValueTracking.h < VectorUtils.h
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:918
+/// Return true if we can that the given load would access only dereferenceable
+/// memory, and be properly aligned on every iteration. (i.e. does not require
----------------
/// Return true if we can [prove] that the given
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:928
+ auto *AddRec = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(Ptr));
+ if (!AddRec || AddRec->getLoop() != L || !AddRec->isAffine())
+ return false;
----------------
What about loads from uniform addresses? If desired their unmasking can be delayed to a later patch, worth leaving a TODO.
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:935
+ APInt LoadSize(DL.getIndexTypeSizeInBits(Ptr->getType()),
+ DL.getTypeStoreSize(LI->getType()));
+ // TODO: generalize to access patterns which don't touch every byte
----------------
indent
"LoadSize"? This refers to the memory size of a single element.
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:936
+ DL.getTypeStoreSize(LI->getType()));
+ // TODO: generalize to access patterns which don't touch every byte
+ if (StepC != LoadSize)
----------------
don't touch every byte >> have gaps
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:942
+ if (!TC)
+ return false;
+
----------------
It would be great to handle symbolic trip counts known to be sufficiently small.
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:945
+ APInt Size(DL.getIndexTypeSizeInBits(Ptr->getType()),
+ TC*DL.getTypeStoreSize(LI->getType()));
+
----------------
"Size"? This refers to the entire memory interval accessed by all iterations of the loop.
Set Size = LoadSize * TC?
Handling gaps would imply (only?) setting Size accordingly, right? That may be useful for unmasking gathers / interleave-groups.
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:948
+ auto *StartS = dyn_cast<SCEVUnknown>(AddRec->getStart());
+ if (!StartS || !SE.isLoopInvariant(StartS, L))
+ return false;
----------------
StartS must be LoopInvariant, iiuc. ("All operands of an AddRec are required to be loop invariant.")
This method is currently employed only by the innermost loop vectorizer; if/when considered by outer loop vectorization, there will be more than a single loop to look after; i.e., StartS may also be an AddRec to check.
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:957
+ Align = DL.getABITypeAlignment(LI->getType());
+ // For the moment, restrict ourselves to the case where the access size is a
+ // multiple of the requested alignment and the base is aligned.
----------------
For the moment - as in TODO?
the access size - of a single element
Do we (need to) check that "the base is aligned"?
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:968
+/// must be proven.
+/// TODO: Move to ValueTracking.h/cpp in a separate change
+static bool mustSuppressSpeculatation(const LoadInst &LI) {
----------------
Can first refactor ValueTracking.h/cpp's isSafeToSpeculativelyExecute().
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:969
+/// TODO: Move to ValueTracking.h/cpp in a separate change
+static bool mustSuppressSpeculatation(const LoadInst &LI) {
+ if (!LI.isUnordered())
----------------
mustSuppressSpecula[ta]tion
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:1007
- for (Instruction &I : *BB)
- if (auto *Ptr = getLoadStorePointerOperand(&I))
- SafePointes.insert(Ptr);
+ // For a block which requires predication, a address may be safe to access
+ // in the loop w/o predication if we can prove dereferenceability facts
----------------
a[n] address
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:1009
+ // in the loop w/o predication if we can prove dereferenceability facts
+ // sufficient to ensure it'll never fault within the loop. For the moment,
+ // we restrict this to loads; stores are more complicated due to
----------------
For the moment - as in TODO?
================
Comment at: lib/Transforms/Vectorize/LoopVectorizationLegality.cpp:1020
+ continue;
+ SafePointes.insert(LI->getPointerOperand());
+ }
----------------
If DL is left to be computed by callee rather than caller, can simplify into:
```
if (LI && !mustSuppressSpeculation(*LI) &&
isDereferenceableAndAlignedInLoop(LI, TheLoop, SE, *DT))
SafePointes.insert(LI->getPointerOperand());
```
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66688/new/
https://reviews.llvm.org/D66688
More information about the llvm-commits
mailing list