[llvm] [SDAG] Disable illegal extract_subvector splitting for scalable vectors (PR #170315)
Benjamin Maxwell via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 2 08:29:41 PST 2025
================
@@ -3938,42 +3938,50 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
GetSplitVector(N->getOperand(0), Lo, Hi);
- uint64_t LoEltsMin = Lo.getValueType().getVectorMinNumElements();
- uint64_t IdxVal = Idx->getAsZExtVal();
+ ElementCount LoElts = Lo.getValueType().getVectorElementCount();
+ ElementCount IdxVal =
+ ElementCount::get(Idx->getAsZExtVal(), SubVT.isScalableVector());
+ uint64_t IdxValMin = IdxVal.getKnownMinValue();
- unsigned NumResultElts = SubVT.getVectorMinNumElements();
+ EVT SrcVT = N->getOperand(0).getValueType();
+ ElementCount NumResultElts = SubVT.getVectorElementCount();
- if (IdxVal < LoEltsMin) {
- // If the extracted elements are all in the low half, do a simple extract.
- if (IdxVal + NumResultElts <= LoEltsMin)
- return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx);
+ // If the extracted elements are all in the low half, do a simple extract.
+ if (ElementCount::isKnownLE(IdxVal + NumResultElts, LoElts))
+ return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx);
+ unsigned LoEltsMin = LoElts.getKnownMinValue();
+ if (IdxValMin < LoEltsMin &&
+ !(SubVT.isScalableVector() || SrcVT.isScalableVector())) {
// Extracted subvector crosses vector split, so we need to blend the two
// halves.
// TODO: May be able to emit partial extract_subvector.
SmallVector<SDValue, 8> Elts;
- Elts.reserve(NumResultElts);
+ Elts.reserve(NumResultElts.getFixedValue());
- DAG.ExtractVectorElements(Lo, Elts, /*Start=*/IdxVal,
- /*Count=*/LoEltsMin - IdxVal);
+ // This is not valid for scalable vectors. If SubVT is scalable, this is the
+ // same as unrolling a scalable dimension (invalid). If ScrVT is scalable,
+ // `Lo[LoEltsMin]` may not be the last element of `Lo`.
+ DAG.ExtractVectorElements(Lo, Elts, /*Start=*/IdxValMin,
+ /*Count=*/LoEltsMin - IdxValMin);
DAG.ExtractVectorElements(Hi, Elts, /*Start=*/0,
/*Count=*/SubVT.getVectorNumElements() -
Elts.size());
return DAG.getBuildVector(SubVT, dl, Elts);
}
- EVT SrcVT = N->getOperand(0).getValueType();
if (SubVT.isScalableVector() == SrcVT.isScalableVector()) {
- uint64_t ExtractIdx = IdxVal - LoEltsMin;
- if (ExtractIdx % NumResultElts == 0)
+ uint64_t ExtractIdx = IdxValMin - LoEltsMin;
+ unsigned NumResultEltsMin = NumResultElts.getKnownMinValue();
+ if (ExtractIdx % NumResultEltsMin == 0)
----------------
MacDue wrote:
Done. I've also added an assertion that the case below this only runs for fixed-length vectors (as it's also invalid for scalable vectors, but I don't think it's reachable in that case).
https://github.com/llvm/llvm-project/pull/170315
More information about the llvm-commits
mailing list