[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