aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
diff options
context:
space:
mode:
authorPhilip Reames <preames@rivosinc.com>2025-07-02 18:16:27 -0700
committerGitHub <noreply@github.com>2025-07-02 18:16:27 -0700
commit220a00239696257a02fe625a4819fcd038e9dd07 (patch)
tree1454a637eaf06803d5f42389ce952525a23bb850 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
parent44bed1af0fb641ce169262ab9fdb15ad76fe72a1 (diff)
downloadllvm-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.cpp33
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) {