================
@@ -32394,6 +32399,61 @@ static bool compareCmp(Value *V, Value *V2, TargetLibraryInfo &TLI,
return IsCompatibility;
}
+bool SLPVectorizerPass::tryToVectorizeListDownwards(ArrayRef<Value *> VL,
+ BoUpSLP &R, unsigned Depth,
+ bool MaxVFOnly) {
+ if (VL.size() <= 1)
+ return false;
+ if (Depth > RecursionMaxDepth)
+ return false;
+ // Collect the single, in-block, isomorphic user of each value. If every
+ // value has such a user, the users form a list one level closer to the sinks
+ // that we can try to reroot the tree at.
+ SmallVector<Value *, 8> UseVL;
+ Instruction *ReprInst = nullptr;
+ for (Value *V : VL) {
+ if (!V->hasOneUse())
+ break;
+ auto *I = dyn_cast<Instruction>(*V->user_begin());
+ if (!I)
+ break;
+ if (I->isTerminator() || isa<CallInst>(I))
+ break;
+ if (isa<InsertElementInst, InsertValueInst, ExtractValueInst,
+ ExtractElementInst>(I))
+ break;
+ if (!ReprInst)
+ ReprInst = I;
+ else if (I->getParent() != ReprInst->getParent())
+ break;
+ if (ReprInst->getOpcode() != I->getOpcode() ||
+ ReprInst->getType() != I->getType())
+ break;
+ UseVL.push_back(I);
+ }
+ // Try the deepest reachable list first: rerooting further down subsumes the
+ // current list as operands of a larger tree.
+ if (UseVL.size() == VL.size() &&
+ tryToVectorizeListDownwards(UseVL, R, Depth + 1, MaxVFOnly))
+ return true;
+ // insertvalue/insertelement bundles can share a result type while their
+ // inserted-value operands differ in type, which would feed buildTree a
+ // mixed-type operand bundle. They are handled by vectorizeInserts, not here.
+ if (isa<InsertElementInst, InsertValueInst, ExtractValueInst,
+ ExtractElementInst>(VL[0]))
+ return false;
+ // The downward use-chain collection above only matches opcodes, so the list
+ // may mix element types. buildTree asserts that a bundle is all-constant or
+ // all-same-type, so guard against mixed-type lists here.
+ if ((allConstant(VL) || allSameType(VL)) &&
+ tryToVectorizeList(VL, R, MaxVFOnly)) {
----------------
amd-bbandlap wrote:
Understood.
I will follow the original bottom-up approach building the graphs directly during the traversal for single-use instructions and restricting special compare handling to compares with external uses.
https://github.com/llvm/llvm-project/pull/210921