[llvm] [LoopVectorize] Add support for vectorisation of more early exit loops (PR #88385)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 23 23:39:04 PDT 2024
================
@@ -1489,4 +1489,82 @@ void InterleaveGroup<Instruction>::addMetadata(Instruction *NewInst) const {
[](std::pair<int, Instruction *> p) { return p.second; });
propagateMetadata(NewInst, VL);
}
+
+bool loopMayFault(const Loop *L, ScalarEvolution *SE,
+ const DenseMap<Value *, SmallVector<const Value *, 16>>
+ &UnderlyingObjects) {
+ auto &DL = L->getHeader()->getModule()->getDataLayout();
+ for (auto &UO : UnderlyingObjects) {
+ // TODO: For now if we encounter more than one underlying object we just
+ // assume it could fault. However, with more analysis it's possible to look
+ // at all of them and calculate a common range of permitted GEP indices.
+ if (UO.second.size() != 1)
+ return true;
+
+ // For now only the simplest cases are permitted, but this could be
+ // extended further.
+ auto *GEP = dyn_cast<GetElementPtrInst>(UO.first);
+ if (!GEP || GEP->getPointerOperand() != UO.second[0])
+ return true;
+
+ // The only current supported case for 2 GEP indices is when accessing an
+ // array, i.e.
+ // getelementptr [32 x i32], ptr %arr, i64 0, i64 %ind
+ Value *GEPInd;
+ Type *GEPElemType;
+ if (GEP->getNumIndices() == 2) {
+ auto *ArrayTy = dyn_cast<ArrayType>(GEP->getSourceElementType());
+ if (!ArrayTy || !isa<ConstantInt>(GEP->getOperand(1)) ||
+ !cast<ConstantInt>(GEP->getOperand(1))->isZero())
+ return true;
+ GEPInd = GEP->getOperand(2);
+ GEPElemType = ArrayTy->getElementType();
+ } else if (GEP->getNumIndices() == 1) {
----------------
fhahn wrote:
Why are those restrictions needed when we later use the SCEV of the GEP? If possible, would be good to use isDereferenceableAndAlignedInLoop instead of duplicating its logic.
https://github.com/llvm/llvm-project/pull/88385
More information about the llvm-commits
mailing list