diff options
author | Philip Reames <preames@rivosinc.com> | 2025-07-02 18:16:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-02 18:16:27 -0700 |
commit | 220a00239696257a02fe625a4819fcd038e9dd07 (patch) | |
tree | 1454a637eaf06803d5f42389ce952525a23bb850 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | |
parent | 44bed1af0fb641ce169262ab9fdb15ad76fe72a1 (diff) | |
download | llvm-220a00239696257a02fe625a4819fcd038e9dd07.zip llvm-220a00239696257a02fe625a4819fcd038e9dd07.tar.gz llvm-220a00239696257a02fe625a4819fcd038e9dd07.tar.bz2 |
[SDAG] Prefer scalar for prefix of vector GEP expansion (#146719)
When generating SDAG for a getelementptr with a vector result, we were
previously generating splats for each scalar operand. This essentially
has the effect of aggressively vectorizing the sequence, and leaving it
later combines to scalarize if profitable.
Instead, we can keep the accumulating address as a scalar for as long as
the prefix of operands allows before lazily converting to vector on the
first vector operand. This both better fits hardware which frequently
has a scalar base on the scatter/gather instructions, and reduces the
addressing cost even when not as otherwise we end up with a scalar to
vector domain crossing for each scalar operand.
Note that constant splat offsets are treated as scalar for the above,
and only variable offsets can force a conversion to vector.
---------
Co-authored-by: Craig Topper <craig.topper@sifive.com>
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 04d6fd5..ecd1ff8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4336,19 +4336,13 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) { auto &TLI = DAG.getTargetLoweringInfo(); GEPNoWrapFlags NW = cast<GEPOperator>(I).getNoWrapFlags(); - // Normalize Vector GEP - all scalar operands should be converted to the - // splat vector. + // For a vector GEP, keep the prefix scalar as long as possible, then + // convert any scalars encountered after the first vector operand to vectors. bool IsVectorGEP = I.getType()->isVectorTy(); ElementCount VectorElementCount = IsVectorGEP ? cast<VectorType>(I.getType())->getElementCount() : ElementCount::getFixed(0); - if (IsVectorGEP && !N.getValueType().isVector()) { - LLVMContext &Context = *DAG.getContext(); - EVT VT = EVT::getVectorVT(Context, N.getValueType(), VectorElementCount); - N = DAG.getSplat(VT, dl, N); - } - for (gep_type_iterator GTI = gep_type_begin(&I), E = gep_type_end(&I); GTI != E; ++GTI) { const Value *Idx = GTI.getOperand(); @@ -4396,7 +4390,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) { APInt Offs = ElementMul * CI->getValue().sextOrTrunc(IdxSize); LLVMContext &Context = *DAG.getContext(); SDValue OffsVal; - if (IsVectorGEP) + if (N.getValueType().isVector()) OffsVal = DAG.getConstant( Offs, dl, EVT::getVectorVT(Context, IdxTy, VectorElementCount)); else @@ -4418,10 +4412,16 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) { // N = N + Idx * ElementMul; SDValue IdxN = getValue(Idx); - if (!IdxN.getValueType().isVector() && IsVectorGEP) { - EVT VT = EVT::getVectorVT(*Context, IdxN.getValueType(), - VectorElementCount); - IdxN = DAG.getSplat(VT, dl, IdxN); + if (IdxN.getValueType().isVector() != N.getValueType().isVector()) { + if (N.getValueType().isVector()) { + EVT VT = EVT::getVectorVT(*Context, IdxN.getValueType(), + VectorElementCount); + IdxN = DAG.getSplat(VT, dl, IdxN); + } else { + EVT VT = + EVT::getVectorVT(*Context, N.getValueType(), VectorElementCount); + N = DAG.getSplat(VT, dl, N); + } } // If the index is smaller or larger than intptr_t, truncate or extend @@ -4442,7 +4442,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) { SDValue VScale = DAG.getNode( ISD::VSCALE, dl, VScaleTy, DAG.getConstant(ElementMul.getZExtValue(), dl, VScaleTy)); - if (IsVectorGEP) + if (N.getValueType().isVector()) VScale = DAG.getSplatVector(N.getValueType(), dl, VScale); IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale, ScaleFlags); @@ -4475,6 +4475,11 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) { } } + if (IsVectorGEP && !N.getValueType().isVector()) { + EVT VT = EVT::getVectorVT(*Context, N.getValueType(), VectorElementCount); + N = DAG.getSplat(VT, dl, N); + } + MVT PtrTy = TLI.getPointerTy(DAG.getDataLayout(), AS); MVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout(), AS); if (IsVectorGEP) { |