diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -2729,6 +2729,31 @@ return splatSplitI64WithVL(DL, VT, Passthru, Scalar, VL, DAG); } +// If a vector_shuffle source is from a same and contiguous (and started with 0 +// index) vector, return the vector. Otherwise, return SDValue(). +static SDValue isOneSourceVECTOR_SHUFFLE(SDValue N0, SDValue N1, + ArrayRef Mask) { + if (N1.isUndef()) + return N0; + + // Both input must be extracts. + if (N0.getOpcode() != ISD::EXTRACT_SUBVECTOR || + N1.getOpcode() != ISD::EXTRACT_SUBVECTOR) + return SDValue(); + + // Extracting from the same source. + SDValue Src = N0.getOperand(0); + if (Src != N1.getOperand(0)) + return SDValue(); + + // Make sure N0 and N1 are continuous. + if (N0.getConstantOperandVal(1) != 0 || + N1.getConstantOperandVal(1) != Mask.size()) + return SDValue(); + + return Src; +} + // Mask can only be this form. // X X X X ... -1 -1 -1 ..., while X is not -1. // X X X X ... must be in ascending order. @@ -2740,22 +2765,8 @@ // In addition, N0 and N1 must from a same vector (or N1 is undef). static bool isVnsrlShuffle(SDValue N0, SDValue N1, ArrayRef Mask, EVT VT, const RISCVSubtarget &Subtarget) { - if (!N1.isUndef()) { - // Both input must be extracts. - if (N0.getOpcode() != ISD::EXTRACT_SUBVECTOR || - N1.getOpcode() != ISD::EXTRACT_SUBVECTOR) - return false; - - // Extracting from the same source. - SDValue Src = N0.getOperand(0); - if (Src != N1.getOperand(0)) - return false; - - // Make sure N0 and N1 are continuous. - if (N0.getConstantOperandVal(1) != 0 || - N1.getConstantOperandVal(1) != Mask.size()) - return false; - } + if (!isOneSourceVECTOR_SHUFFLE(N0, N1, Mask)) + return false; if (Mask.size() < 2) return false; // Find first -1 and check whether the mask behind is -1. @@ -2962,22 +2973,9 @@ ArrayRef Mask, const RISCVSubtarget &Subtarget, SelectionDAG &DAG) { - // Both input must be extracts. - if (V1.getOpcode() != ISD::EXTRACT_SUBVECTOR || - V2.getOpcode() != ISD::EXTRACT_SUBVECTOR) + SDValue Src = isOneSourceVECTOR_SHUFFLE(V1, V2, Mask); + if (!Src) return SDValue(); - - // Extracting from the same source. - SDValue Src = V1.getOperand(0); - if (Src != V2.getOperand(0)) - return SDValue(); - - // V1 must be started with 0. - // V1 and V2 are continuous. - if (V1.getConstantOperandVal(1) != 0 || - VT.getVectorNumElements() != V2.getConstantOperandVal(1)) - return SDValue(); - // First index must be known and non-zero. It will be used as the slidedown // amount. if (Mask[0] <= 0)