[llvm] [SLP] Support memory runtime alias checks (PR #203631)
Ryan Buchner via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 23 11:49:09 PDT 2026
================
@@ -27641,14 +28359,65 @@ bool SLPVectorizerPass::runImpl(Function &F, ScalarEvolution *SE_,
R.optimizeGatherSequence();
LLVM_DEBUG(dbgs() << "SLP: vectorized \"" << F.getName() << "\"\n");
}
+ // Propagate whether runtime alias check versioning changed the CFG, so the
+ // caller can drop CFG-analysis preservation only when necessary.
+ CFGChanged = R.isCFGChanged();
return Changed;
}
std::optional<bool>
SLPVectorizerPass::vectorizeStoreChain(ArrayRef<Value *> Chain, BoUpSLP &R,
unsigned Idx, unsigned MinVF,
unsigned &Size) {
+ std::optional<bool> Res = vectorizeStoreChainImpl(Chain, R, Idx, MinVF, Size);
+ assert(!R.isTryingRuntimeAliasChecks() &&
+ "Unexpected nested runtime alias check attempt");
+ // Retry once with runtime alias checks, but only when the normal attempt
+ // could not even schedule the bundle, i.e. it was blocked by
+ // a memory dependency, and that dependency is runtime-checkable. If the
+ // region also kept a non-checkable blocker, dropping the checkable deps
+ // cannot unblock it.
+ if (Res.has_value() || !SLPEnableRuntimeAliasChecks ||
+ !R.hasRuntimeCheckableBlockers() || R.hasNonCheckableMemBlocker())
+ return Res;
+ // Only retry when scheduling blocked the chain (a store or its value bundle
+ // could not be scheduled), which dropping may-alias deps can fix. A chain
+ // gathered for structural reasons (e.g. non-consecutive addresses) would
+ // gather again, so the second buildTree() would be pure overhead with no
+ // vectorization benefit.
+ Value *FirstStore = Chain.front();
+ if (!R.isNotScheduled(FirstStore) &&
+ !R.isNotScheduled(cast<StoreInst>(FirstStore)->getValueOperand()))
+ return Res;
+ BasicBlock *BB = cast<Instruction>(FirstStore)->getParent();
+ // If an earlier optimistic attempt already failed for this block, do not
+ // retry for other chains or smaller VFs in the same block.
+ if (R.runtimeChecksFailedForBlock(BB))
+ return Res;
+ // The retry rebuilds the whole tree; also skip it when the chain's block can
+ // never be versioned (e.g. it is inside a loop).
+ if (!R.canVersionBlockForRuntimeChecks(BB))
+ return Res;
+ R.setTryRuntimeAliasChecks(true);
+ unsigned RTSize = Size;
+ std::optional<bool> RTRes =
+ vectorizeStoreChainImpl(Chain, R, Idx, MinVF, RTSize);
+ R.setTryRuntimeAliasChecks(false);
+ if (RTRes && *RTRes) {
+ Size = RTSize;
+ return RTRes;
+ }
+ // The versioning attempt failed for this block, skip the (expensive) retry.
+ R.markRuntimeChecksFailedForBlock(BB);
+ return Res;
----------------
bababuck wrote:
I understand if this is the best option from a compile time perspective, but it does seem overly restrictive.
https://github.com/llvm/llvm-project/pull/203631
More information about the llvm-commits
mailing list