[llvm] a1cab0d - [LV] Use cost base decision for uniform mem op strategy [nfc-ish]
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 3 07:48:06 PDT 2022
Author: Philip Reames
Date: 2022-08-03T07:47:24-07:00
New Revision: a1cab0daae43ad2c81e30e73d250b05e64963065
URL: https://github.com/llvm/llvm-project/commit/a1cab0daae43ad2c81e30e73d250b05e64963065
DIFF: https://github.com/llvm/llvm-project/commit/a1cab0daae43ad2c81e30e73d250b05e64963065.diff
LOG: [LV] Use cost base decision for uniform mem op strategy [nfc-ish]
This is mostly a stylistic change to make the uniform memop widening cost
code fit more naturally with the sourounding code. Its not strictly
speaking NFC as I added in the store with invariant value case, and we
could in theory have a target where a gather/scatter is cheaper than a
single load/store... but it's probably NFC in practice. Note that the
scatter/gather result can still be overriden later if the result is
uniform-by-parts.
Added:
Modified:
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 76e7e2a15e1b1..db9dd543fdd2e 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6775,29 +6775,41 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
NumPredStores++;
if (Legal->isUniformMemOp(I)) {
- // Lowering story for uniform memory ops is currently a bit complicated.
- // Scalarization works for everything which isn't a store with scalable
- // VF. Fixed len VFs just scalarize and then DCE later; scalarization
- // knows how to handle uniform-per-part values (i.e. the first lane
- // in each unrolled VF) and can thus handle scalable loads too. For
- // scalable stores, we use a scatter if legal. If not, we have no way
- // to lower (currently) and thus have to abort vectorization.
- if (isa<StoreInst>(&I) && VF.isScalable()) {
- if (isLegalGatherOrScatter(&I, VF))
- setWideningDecision(&I, VF, CM_GatherScatter,
- getGatherScatterCost(&I, VF));
- else
- // Error case, abort vectorization
- setWideningDecision(&I, VF, CM_Scalarize,
- InstructionCost::getInvalid());
- continue;
- }
+ auto isLegalToScalarize = [&]() {
+ if (!VF.isScalable())
+ // Scalarization of fixed length vectors "just works".
+ return true;
+
+ // For scalable vectors, a uniform memop load is always
+ // uniform-by-parts and we know how to scalarize that.
+ if (isa<LoadInst>(I))
+ return true;
+
+ // A uniform store isn't neccessarily uniform-by-part
+ // and we can't assume scalarization.
+ auto &SI = cast<StoreInst>(I);
+ return TheLoop->isLoopInvariant(SI.getValueOperand());
+ };
+
+ const InstructionCost GatherScatterCost =
+ isLegalGatherOrScatter(&I, VF) ?
+ getGatherScatterCost(&I, VF) : InstructionCost::getInvalid();
+
// Load: Scalar load + broadcast
// Store: Scalar store + isLoopInvariantStoreValue ? 0 : extract
// TODO: Avoid replicating loads and stores instead of relying on
// instcombine to remove them.
- setWideningDecision(&I, VF, CM_Scalarize,
- getUniformMemOpCost(&I, VF));
+ const InstructionCost ScalarizationCost = isLegalToScalarize() ?
+ getUniformMemOpCost(&I, VF) : InstructionCost::getInvalid();
+
+
+ // Choose better solution for the current VF, Note that Invalid
+ // costs compare as maximumal large. If both are invalid, we get
+ // scalable invalid which signals a failure and a vectorization abort.
+ if (GatherScatterCost < ScalarizationCost)
+ setWideningDecision(&I, VF, CM_GatherScatter, GatherScatterCost);
+ else
+ setWideningDecision(&I, VF, CM_Scalarize, ScalarizationCost);
continue;
}
More information about the llvm-commits
mailing list