diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 17703f58f2824..d343b644e41cb 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -26018,7 +26018,10 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode *N) { // Combine an extract of an extract into a single extract_subvector. // ext (ext X, C), 0 --> ext X, C if (ExtIdx == 0 && V.getOpcode() == ISD::EXTRACT_SUBVECTOR && V.hasOneUse()) { - if (TLI.isExtractSubvectorCheap(NVT, V.getOperand(0).getValueType(), + // The index has to be a multiple of the new result type's known minimum + // vector length. + if (V.getConstantOperandVal(1) % NVT.getVectorMinNumElements() == 0 && + TLI.isExtractSubvectorCheap(NVT, V.getOperand(0).getValueType(), V.getConstantOperandVal(1)) && TLI.isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, NVT)) { return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NVT, V.getOperand(0), diff --git a/llvm/test/CodeGen/RISCV/rvv/incorrect-extract-subvector-combine.ll b/llvm/test/CodeGen/RISCV/rvv/incorrect-extract-subvector-combine.ll new file mode 100644 index 0000000000000..6a0c03f339717 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/incorrect-extract-subvector-combine.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=riscv64 -mattr='+zve64f,+zvl512b' < %s | FileCheck %s + +; Previously, an incorrect (extract_subvector (extract_subvector X, C), 0) DAG combine crashed +; this snippet. + +define <8 x i16> @gsm_encode() { +; CHECK-LABEL: gsm_encode: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetivli zero, 19, e16, m1, ta, ma +; CHECK-NEXT: vle16.v v8, (zero) +; CHECK-NEXT: vslidedown.vi v9, v8, 12 +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: vsetivli zero, 8, e16, mf4, ta, ma +; CHECK-NEXT: vmv.v.i v9, -1 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 9 +; CHECK-NEXT: vmv.x.s a1, v8 +; CHECK-NEXT: vsetivli zero, 8, e16, mf4, ta, ma +; CHECK-NEXT: vmv.v.i v8, 0 +; CHECK-NEXT: vslide1down.vx v9, v9, zero +; CHECK-NEXT: vslide1down.vx v8, v8, zero +; CHECK-NEXT: vslide1down.vx v8, v8, zero +; CHECK-NEXT: vslide1down.vx v8, v8, zero +; CHECK-NEXT: vslide1down.vx v8, v8, zero +; CHECK-NEXT: vslide1down.vx v8, v8, a1 +; CHECK-NEXT: vslide1down.vx v8, v8, a0 +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: vand.vv v8, v8, v9 +; CHECK-NEXT: ret +entry: + %0 = load <19 x i16>, ptr null, align 2 + %1 = shufflevector <19 x i16> zeroinitializer, <19 x i16> %0, <9 x i32> + %2 = shufflevector <9 x i16> %1, <9 x i16> zeroinitializer, <8 x i32> + ret <8 x i16> %2 +}