After introducing VPWidenSelectRecipe, the duplicated logic can be
shared.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Yes, this follows D77972 naturally :-)
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
6935 | Can add !isa<PHINode>(I) to this assertion list after sinking tryToWidenSelect() as suggested below. | |
7093 | How about doing here (tryToCreateRecipe should have a better name btw): if (!shouldWiden(I, Range)) return false; if ((Recipe = tryToWidenSelect(Instr)) || (isa<GetElementPtrInst>(Instr) && (Recipe = new VPWidenGEPRecipe(GEP, OrigLoop)))) || (Recipe = tryToWiden(Instr, *Plan))) { setRecipe(Instr, Recipe); VPBB->appendRecipe(Recipe); return true; } return false; } |
Consolidate widening checks for GEP, Select and general widening as suggested in tryToCreateRecipe.
Thanks for cleaning this up! Final couple of nits.
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
6935 | Retain the !isa<Call, Load, Store> alongside !isa<PHI>? | |
6942 | More natural to reverse the conditions and rename willWiden to willScalarize, returning !getDecisionAndClampRange(willScalarize, Range)? | |
6966 | Branches should also find their way out of IsVectorizableOpcode and into an assert; no recipes are created for them. |
Avoid calling shouldWiden for calls, loads and stores by exiting earlier. They should be widened by the specialized recipes or scalarized.
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
6935 | Ahh, right. Perhaps better to early-exit here: // Calls and memory instructions that were not widened earlier should be scalarized. if (isa<CallInst>(Instr) || isa<LoadInst>(Instr) || isa<StoreInst>(Instr)) return false; assert(!isa<PHINode>(I) && ...); | |
6966 | Sure. |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
6935 | Is there an advantage to have the early exit here? To me it seems to fit slightly better at the call site of shouldWiden, because there it is clearer what is happening (i.e. the code to handle calls, stores, loads is just above.) |
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | ||
---|---|---|
6935 | Your original version is fine, as approved. Advantage of last suggestion was merely to avoid an obvious assert immediately following an early-exiting. Thoughts of further cleanup:
VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(Instruction *Instr, VFRange &Range, VPlanPtr &Plan) { if (auto *CI = dyn_cast<CallInst>(Instr)) return tryToWidenCall(CI, Range, *Plan); if (isa<LoadInst>(Instr) || isa<StoreInst>(Instr)) return tryToWidenMemory(Instr, Range, Plan); if (auto *PHI = dyn_cast<PHINode>(Instr)) { if (auto *Recipe = tryToOptimizeInduction(PHI, Range)) return Recipe; if (auto *Recipe = tryToBlend(PHI, Plan)) return Recipe; return new VPWidenPHIRecipe(PHI); } if (auto *Trunc = dyn_cast<TruncInst>(Instr)) if (auto *Recipe = tryToOptimizeIVTruncate(Trunc, Range)) return Recipe; if (!shouldWiden(Instr, Range)) return nullptr; if (auto *GEP = dyn_cast<GetElementPtrInst>(Instr)) return new VPWidenGEPRecipe(GEP, OrigLoop); if (auto *Select = dyn_cast<SelectInst<(Instr)) return tryToWidenSelect(Instr); return tryToWiden(Instr, *Plan); } |
Can add !isa<PHINode>(I) to this assertion list after sinking tryToWidenSelect() as suggested below.