================
@@ -27493,6 +27493,65 @@ static SDValue 
foldExtractSubvectorFromShuffleVector(EVT NarrowVT, SDValue Src,
   return DAG.getVectorShuffle(NarrowVT, DL, NewOps[0], NewOps[1], NewMask);
 }
 
+static SDValue foldExtractSubvectorFromConcatVectors(EVT VT, SDValue V,
+                                                     uint64_t ExtIdx,
+                                                     const SDLoc &DL,
+                                                     SelectionDAG &DAG,
+                                                     bool LegalOperations) {
+  if (V.getOpcode() != ISD::CONCAT_VECTORS)
+    return SDValue();
+
+  unsigned ExtNumElts = VT.getVectorMinNumElements();
+  EVT ConcatSrcVT = V.getOperand(0).getValueType();
+  assert(ConcatSrcVT.getVectorElementType() == VT.getVectorElementType() &&
+         "Concat and extract subvector do not change element type");
+
+  unsigned ConcatSrcNumElts = ConcatSrcVT.getVectorMinNumElements();
+  unsigned ConcatOpIdx = ExtIdx / ConcatSrcNumElts;
+  if (ConcatOpIdx >= V.getNumOperands())
+    return SDValue();
+
+  // If the concatenated source types match this extract, it's a direct
+  // simplification:
+  // extract_subvec (concat V1, V2, ...), i --> Vi
+  if (VT.getVectorElementCount() == ConcatSrcVT.getVectorElementCount())
+    return V.getOperand(ConcatOpIdx);
+
+  // Patterns after here are fixed-length only.
+  if (!VT.isFixedLengthVector() || !ConcatSrcVT.isFixedLengthVector())
+    return SDValue();
+
+  // If the concatenated source vectors are a multiple length of this extract,
+  // then extract a fraction of one of those source vectors directly from a
+  // concat operand. Example:
+  //   v2i8 extract_subvec (v16i8 concat (v8i8 X), (v8i8 Y)), 14 -->
+  //   v2i8 extract_subvec v8i8 Y, 6
+  if (ConcatSrcNumElts % ExtNumElts == 0) {
+    uint64_t NewExtIdx = ExtIdx - ConcatOpIdx * ConcatSrcNumElts;
+    if (NewExtIdx + ExtNumElts > ConcatSrcNumElts)
+      return SDValue();
+    return DAG.getExtractSubvector(DL, VT, V.getOperand(ConcatOpIdx),
+                                   NewExtIdx);
+  }
+
+  // If the extract covers multiple whole concat operands, rebuild that smaller
+  // concat directly.
+  bool IsPermittedConcat =
+      !LegalOperations || DAG.getTargetLoweringInfo().isOperationLegalOrCustom(
+                              ISD::CONCAT_VECTORS, VT);
+  if (ExtNumElts % ConcatSrcNumElts == 0 && ExtIdx % ConcatSrcNumElts == 0 &&
+      IsPermittedConcat) {
+    unsigned NumConcatOps = ExtNumElts / ConcatSrcNumElts;
+    if (ConcatOpIdx + NumConcatOps > V.getNumOperands())
+      return SDValue();
+
+    return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT,
+                       V->ops().slice(ConcatOpIdx, NumConcatOps));
+  }
----------------
paulwalker-arm wrote:

Is there a reason the new transformation is being restricted to fixed length 
vectors? Other than changing the maths to be ElementCount based, it seems 
applicable to scalable vectors as well? Or rather, can the combine can be 
written to be agnostic of the vector type other than requiring `VT.isScalable() 
== ConcatSrcVT.isScalable()`?

https://github.com/llvm/llvm-project/pull/200936
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to