[llvm] 875aed1 - [X86] Add combineExtractFromVectorLoad helper - pulled out of combineExtractVectorElt
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 27 05:23:03 PDT 2024
Author: Simon Pilgrim
Date: 2024-03-27T12:22:31Z
New Revision: 875aed17b978bf58a01d31572af6964e91a9f641
URL: https://github.com/llvm/llvm-project/commit/875aed17b978bf58a01d31572af6964e91a9f641
DIFF: https://github.com/llvm/llvm-project/commit/875aed17b978bf58a01d31572af6964e91a9f641.diff
LOG: [X86] Add combineExtractFromVectorLoad helper - pulled out of combineExtractVectorElt
Prep work for #85419 to make it easier to reuse in other combines
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9bad38f97c6a29..4cd0bebe01bb48 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -43995,6 +43995,49 @@ static SDValue combineBasicSADPattern(SDNode *Extract, SelectionDAG &DAG,
Extract->getOperand(1));
}
+// If this extract is from a loaded vector value and will be used as an
+// integer, that requires a potentially expensive XMM -> GPR transfer.
+// Additionally, if we can convert to a scalar integer load, that will likely
+// be folded into a subsequent integer op.
+// Note: Unlike the related fold for this in DAGCombiner, this is not limited
+// to a single-use of the loaded vector. For the reasons above, we
+// expect this to be profitable even if it creates an extra load.
+static SDValue
+combineExtractFromVectorLoad(SDNode *N, SDValue InputVector, uint64_t Idx,
+ const SDLoc &dl, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ assert(N->getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
+ "Only EXTRACT_VECTOR_ELT supported so far");
+
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ EVT SrcVT = InputVector.getValueType();
+ EVT VT = N->getValueType(0);
+
+ bool LikelyUsedAsVector = any_of(N->uses(), [](SDNode *Use) {
+ return Use->getOpcode() == ISD::STORE ||
+ Use->getOpcode() == ISD::INSERT_VECTOR_ELT ||
+ Use->getOpcode() == ISD::SCALAR_TO_VECTOR;
+ });
+
+ auto *LoadVec = dyn_cast<LoadSDNode>(InputVector);
+ if (LoadVec && ISD::isNormalLoad(LoadVec) && VT.isInteger() &&
+ SrcVT.getVectorElementType() == VT && DCI.isAfterLegalizeDAG() &&
+ !LikelyUsedAsVector && LoadVec->isSimple()) {
+ SDValue NewPtr = TLI.getVectorElementPointer(
+ DAG, LoadVec->getBasePtr(), SrcVT, DAG.getVectorIdxConstant(Idx, dl));
+ unsigned PtrOff = VT.getSizeInBits() * Idx / 8;
+ MachinePointerInfo MPI = LoadVec->getPointerInfo().getWithOffset(PtrOff);
+ Align Alignment = commonAlignment(LoadVec->getAlign(), PtrOff);
+ SDValue Load =
+ DAG.getLoad(VT, dl, LoadVec->getChain(), NewPtr, MPI, Alignment,
+ LoadVec->getMemOperand()->getFlags(), LoadVec->getAAInfo());
+ DAG.makeEquivalentMemoryOrdering(LoadVec, Load);
+ return Load;
+ }
+
+ return SDValue();
+}
+
// Attempt to peek through a target shuffle and extract the scalar from the
// source.
static SDValue combineExtractWithShuffle(SDNode *N, SelectionDAG &DAG,
@@ -44600,6 +44643,11 @@ static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG,
if (SDValue V = scalarizeExtEltFP(N, DAG, Subtarget))
return V;
+ if (CIdx)
+ if (SDValue V = combineExtractFromVectorLoad(
+ N, InputVector, CIdx->getZExtValue(), dl, DAG, DCI))
+ return V;
+
// Attempt to extract a i1 element by using MOVMSK to extract the signbits
// and then testing the relevant element.
//
@@ -44645,34 +44693,6 @@ static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG,
}
}
- // If this extract is from a loaded vector value and will be used as an
- // integer, that requires a potentially expensive XMM -> GPR transfer.
- // Additionally, if we can convert to a scalar integer load, that will likely
- // be folded into a subsequent integer op.
- // Note: Unlike the related fold for this in DAGCombiner, this is not limited
- // to a single-use of the loaded vector. For the reasons above, we
- // expect this to be profitable even if it creates an extra load.
- bool LikelyUsedAsVector = any_of(N->uses(), [](SDNode *Use) {
- return Use->getOpcode() == ISD::STORE ||
- Use->getOpcode() == ISD::INSERT_VECTOR_ELT ||
- Use->getOpcode() == ISD::SCALAR_TO_VECTOR;
- });
- auto *LoadVec = dyn_cast<LoadSDNode>(InputVector);
- if (LoadVec && CIdx && ISD::isNormalLoad(LoadVec) && VT.isInteger() &&
- SrcVT.getVectorElementType() == VT && DCI.isAfterLegalizeDAG() &&
- !LikelyUsedAsVector && LoadVec->isSimple()) {
- SDValue NewPtr =
- TLI.getVectorElementPointer(DAG, LoadVec->getBasePtr(), SrcVT, EltIdx);
- unsigned PtrOff = VT.getSizeInBits() * CIdx->getZExtValue() / 8;
- MachinePointerInfo MPI = LoadVec->getPointerInfo().getWithOffset(PtrOff);
- Align Alignment = commonAlignment(LoadVec->getAlign(), PtrOff);
- SDValue Load =
- DAG.getLoad(VT, dl, LoadVec->getChain(), NewPtr, MPI, Alignment,
- LoadVec->getMemOperand()->getFlags(), LoadVec->getAAInfo());
- DAG.makeEquivalentMemoryOrdering(LoadVec, Load);
- return Load;
- }
-
return SDValue();
}
@@ -48273,7 +48293,7 @@ static SDValue combineAndShuffleNot(SDNode *N, SelectionDAG &DAG,
// We do not split for SSE at all, but we need to split vectors for AVX1 and
// AVX2.
- if (!Subtarget.useAVX512Regs() && VT.is512BitVector() &&
+ if (!Subtarget.useAVX512Regs() && VT.is512BitVector() &&
TLI.isTypeLegal(VT.getHalfNumVectorElementsVT(*DAG.getContext()))) {
SDValue LoX, HiX;
std::tie(LoX, HiX) = splitVector(X, DAG, DL);
More information about the llvm-commits
mailing list