[PATCH] D104232: [WIP][DAGCombiner] createBuildVecShuffle(): more vector concatenation

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 14 08:20:32 PDT 2021


lebedev.ri created this revision.
lebedev.ri added reviewers: RKSimon, mkuper.
lebedev.ri added a project: LLVM.
Herald added subscribers: ecnelises, hiraditya.
lebedev.ri requested review of this revision.

While i'm quite sure this is correct and optimal,
i'm having trouble coming up with a test case to demonstrate this.

llvm-stress provided a few snippets that showcase codegen differences
(https://godbolt.org/z/7G3T45cxq), but i can't quite turn them into something reasonable that i feel ok using as a codegen test :)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104232

Files:
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19097,16 +19097,33 @@
   // We can't generate a shuffle node with mismatched input and output types.
   // Try to make the types match the type of the output.
   if (InVT1 != VT || InVT2 != VT) {
-    if ((VTSize % InVT1Size == 0) && InVT1 == InVT2) {
-      // If the output vector length is a multiple of both input lengths,
-      // we can concatenate them and pad the rest with undefs.
-      unsigned NumConcats = VTSize / InVT1Size;
-      assert(NumConcats >= 2 && "Concat needs at least two inputs!");
-      SmallVector<SDValue, 2> ConcatOps(NumConcats, DAG.getUNDEF(InVT1));
-      ConcatOps[0] = VecIn1;
-      ConcatOps[1] = VecIn2 ? VecIn2 : DAG.getUNDEF(InVT1);
-      VecIn1 = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ConcatOps);
-      VecIn2 = SDValue();
+    if ((VTSize % InVT1Size == 0) && (InVT1Size % InVT2Size == 0)) {
+      // If the output vector length is a multiple of first input length, and
+      // the first vector length is a multiple of second input length, then we
+      // can firstly pad the second input until it's length equates with the
+      // length of first input, and afterwards, if their lenghts aren't equal
+      // to the output vector length, then concatenate them and pad the rest.
+      if (InVT2Size != InVT1Size) {
+        unsigned NumConcats = InVT1Size / InVT2Size;
+        assert(NumConcats >= 2 && "Concat needs at least two inputs!");
+        SmallVector<SDValue, 2> ConcatOps(NumConcats, DAG.getUNDEF(InVT2));
+        ConcatOps[0] = VecIn2;
+        VecIn2 = DAG.getNode(ISD::CONCAT_VECTORS, DL, InVT1, ConcatOps);
+        InVT2 = VecIn2.getValueType();
+        InVT2Size = InVT2.getFixedSizeInBits();
+      }
+      assert(InVT1Size == InVT2Size && "The inputs now have the same length.");
+
+      if (InVT1Size != VTSize) {
+        unsigned NumConcats = VTSize / InVT1Size;
+        assert(NumConcats >= 2 && "Concat needs at least two inputs!");
+        SmallVector<SDValue, 2> ConcatOps(NumConcats, DAG.getUNDEF(InVT1));
+        ConcatOps[0] = VecIn1;
+        if (VecIn2)
+          ConcatOps[1] = VecIn2;
+        VecIn1 = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ConcatOps);
+        VecIn2 = SDValue();
+      }
     } else if (InVT1Size == VTSize * 2) {
       if (!TLI.isExtractSubvectorCheap(VT, InVT1, NumElems))
         return SDValue();
@@ -19143,10 +19160,6 @@
         }
         ShuffleNumElems = NumElems * 2;
       }
-    } else if (InVT2Size * 2 == VTSize && InVT1Size == VTSize) {
-      SmallVector<SDValue, 2> ConcatOps(2, DAG.getUNDEF(InVT2));
-      ConcatOps[0] = VecIn2;
-      VecIn2 = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, ConcatOps);
     } else {
       // TODO: Support cases where the length mismatch isn't exactly by a
       // factor of 2.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104232.351879.patch
Type: text/x-patch
Size: 2983 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210614/c2107465/attachment.bin>


More information about the llvm-commits mailing list