[llvm] [SLP]Initial support for copyable elements (non-schedulable only) (PR #140279)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 11 08:47:52 PDT 2025
================
@@ -9907,22 +10097,122 @@ class InstructionsCompatibilityAnalysis {
const TargetLibraryInfo &TLI)
: DT(DT), DL(DL), TTI(TTI), TLI(TLI) {}
+ InstructionsState
+ buildInstructionsState(ArrayRef<Value *> VL, const BoUpSLP &R,
+ bool TryCopyableElementsVectorization,
+ bool WithProfitabilityCheck = false) {
+ InstructionsState S = getSameOpcode(VL, TLI);
+ if (S)
+ return S;
+ if (!VectorizeCopyableElements || !TryCopyableElementsVectorization)
+ return S;
+ findAndSetMainInstruction(VL);
+ if (!MainOp)
+ return InstructionsState::invalid();
+ S = InstructionsState(MainOp, MainOp);
+ if (!WithProfitabilityCheck)
+ return S;
+ // Check if it is profitable to vectorize the instruction.
+ SmallVector<BoUpSLP::ValueList> Operands = buildOperands(S, VL);
+ if (VL.size() == 2) {
+ // Check if the operands allow better vectorization.
+ SmallVector<std::pair<Value *, Value *>, 4> Candidates;
+ Candidates.emplace_back(Operands[0][0], Operands[0][1]);
+ Candidates.emplace_back(Operands[1][0], Operands[1][1]);
+ if (isCommutative(MainOp)) {
+ Candidates.emplace_back(Operands[0][0], Operands[1][1]);
+ Candidates.emplace_back(Operands[1][0], Operands[0][1]);
+ }
+ // No good candidates - not profitable.
+ if (!R.findBestRootPair(Candidates,
+ BoUpSLP::LookAheadHeuristics::ScoreSplat)) {
+ // Deeper analysis for 2 splats/constants.
+ SmallVector<std::pair<Value *, Value *>, 4> Candidates1, Candidates2;
+ Candidates1.emplace_back(Operands[0][0], Operands[0][1]);
+ Candidates2.emplace_back(Operands[1][0], Operands[1][1]);
+ bool Res =
+ R.findBestRootPair(Candidates1) && R.findBestRootPair(Candidates2);
+ if (!Res && isCommutative(MainOp)) {
+ Candidates1.clear();
+ Candidates2.clear();
+ Candidates1.emplace_back(Operands[0][0], Operands[1][1]);
+ Candidates2.emplace_back(Operands[1][0], Operands[0][1]);
+ Res = R.findBestRootPair(Candidates1) &&
+ R.findBestRootPair(Candidates2);
+ }
+ if (!Res)
+ return InstructionsState::invalid();
+ }
+ }
+ assert(Operands.size() == 2 && "Unexpected number of operands!");
+ unsigned CopyableNum =
+ count_if(VL, [&](Value *V) { return S.isCopyableElement(V); });
+ if (CopyableNum <= VL.size() / 2)
+ return S;
+ // Check profitability if number of copyables > VL.size() / 2.
+ // 1. Reorder operands for better matching.
+ if (isCommutative(MainOp)) {
+ for (auto &Ops : Operands) {
+ // Make instructions the first operands.
+ if (isa<Instruction>(Ops.back())) {
----------------
RKSimon wrote:
so we always commute even if front() is already an Instruction?
https://github.com/llvm/llvm-project/pull/140279
More information about the llvm-commits
mailing list