[llvm] [VPlan] Simplify WidenGEP::execute (PR #193543)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 9 21:56:41 PDT 2026
================
@@ -3004,65 +3004,27 @@ bool VPWidenGEPRecipe::usesFirstLaneOnly(const VPValue *Op) const {
void VPWidenGEPRecipe::execute(VPTransformState &State) {
assert(State.VF.isVector() && "not widening");
- // Construct a vector GEP by widening the operands of the scalar GEP as
- // necessary. We mark the vector GEP 'inbounds' if appropriate. A GEP
- // results in a vector of pointers when at least one operand of the GEP
- // is vector-typed. Thus, to keep the representation compact, we only use
- // vector-typed operands for loop-varying values.
-
- bool AllOperandsAreInvariant = all_of(operands(), [](VPValue *Op) {
- return Op->isDefinedOutsideLoopRegions();
+ auto Ops = map_to_vector(operands(), [&](VPValue *Op) {
+ return State.get(Op, vputils::isSingleScalar(Op));
});
- if (AllOperandsAreInvariant) {
- // If we are vectorizing, but the GEP has only loop-invariant operands,
- // the GEP we build (by only using vector-typed operands for
- // loop-varying values) would be a scalar pointer. Thus, to ensure we
- // produce a vector of pointers, we need to either arbitrarily pick an
- // operand to broadcast, or broadcast a clone of the original GEP.
- // Here, we broadcast a clone of the original.
-
- SmallVector<Value *> Ops;
- for (unsigned I = 0, E = getNumOperands(); I != E; I++)
- Ops.push_back(State.get(getOperand(I), VPLane(0)));
-
- auto *NewGEP =
- State.Builder.CreateGEP(getSourceElementType(), Ops[0], drop_begin(Ops),
- "", getGEPNoWrapFlags());
- Value *Splat = State.Builder.CreateVectorSplat(State.VF, NewGEP);
- State.set(this, Splat);
- return;
- }
-
- // If the GEP has at least one loop-varying operand, we are sure to
- // produce a vector of pointers unless VF is scalar.
- // The pointer operand of the new GEP. If it's loop-invariant, we
- // won't broadcast it.
- auto *Ptr = State.get(getOperand(0), isPointerLoopInvariant());
-
- // Collect all the indices for the new GEP. If any index is
- // loop-invariant, we won't broadcast it.
- SmallVector<Value *, 4> Indices;
- for (unsigned I = 1, E = getNumOperands(); I < E; I++) {
- VPValue *Operand = getOperand(I);
- Indices.push_back(State.get(Operand, isIndexLoopInvariant(I - 1)));
- }
-
- // Create the new GEP. Note that this GEP may be a scalar if VF == 1,
- // but it should be a vector, otherwise.
- auto *NewGEP = State.Builder.CreateGEP(getSourceElementType(), Ptr, Indices,
- "", getGEPNoWrapFlags());
- assert((State.VF.isScalar() || NewGEP->getType()->isVectorTy()) &&
- "NewGEP is not a pointer vector");
- State.set(this, NewGEP);
+ auto *GEP =
+ State.Builder.CreateGEP(getSourceElementType(), Ops.front(),
+ drop_begin(Ops), "wide.gep", getGEPNoWrapFlags());
+ State.set(this, GEP, vputils::isSingleScalar(this));
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void VPWidenGEPRecipe::printRecipe(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
+ bool IsPointerLoopInvariant = getOperand(0)->isDefinedOutsideLoopRegions();
+ auto IsIndexLoopInvariant = [this](unsigned I) {
+ return getOperand(I + 1)->isDefinedOutsideLoopRegions();
+ };
+
O << Indent << "WIDEN-GEP ";
- O << (isPointerLoopInvariant() ? "Inv" : "Var");
+ O << (IsPointerLoopInvariant ? "Inv" : "Var");
for (size_t I = 0; I < getNumOperands() - 1; ++I)
- O << "[" << (isIndexLoopInvariant(I) ? "Inv" : "Var") << "]";
+ O << "[" << (IsIndexLoopInvariant(I) ? "Inv" : "Var") << "]";
----------------
lukel97 wrote:
I wouldn't be opposed to just removing the Inv/Var printing given that it doesn't mean anything anymore
https://github.com/llvm/llvm-project/pull/193543
More information about the llvm-commits
mailing list