================
@@ -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));
+  }
----------------
krzysz00 wrote:

Yeah, I think this could all work on scalable vectors, if I've understood how 
those work correctly. Will try to scare up some tests for those.

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