diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/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 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 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 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 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.