[llvm] [DAGCombine] Fix an incorrect folding of extract_subvector (PR #153709)
Min-Yih Hsu via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 14 16:03:46 PDT 2025
https://github.com/mshockwave updated https://github.com/llvm/llvm-project/pull/153709
>From 2d8d901679b45fec39d0ac2c814e9fc3b49c4a72 Mon Sep 17 00:00:00 2001
From: Min-Yih Hsu <min.hsu at sifive.com>
Date: Thu, 14 Aug 2025 15:45:01 -0700
Subject: [PATCH 1/2] [DAGCombine] Fix an incorrect folding of
extract_subvector
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 ++-
.../incorrect-extract-subvector-combine.ll | 36 +++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/RISCV/rvv/incorrect-extract-subvector-combine.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 17703f58f2824..feb8f8556067b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -26020,7 +26020,10 @@ SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode *N) {
if (ExtIdx == 0 && V.getOpcode() == ISD::EXTRACT_SUBVECTOR && V.hasOneUse()) {
if (TLI.isExtractSubvectorCheap(NVT, V.getOperand(0).getValueType(),
V.getConstantOperandVal(1)) &&
- TLI.isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, NVT)) {
+ TLI.isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, NVT) &&
+ // The index has to be a multiple of the new result type's known minimum
+ // vector length.
+ V.getConstantOperandVal(1) % NVT.getVectorMinNumElements() == 0) {
return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NVT, V.getOperand(0),
V.getOperand(1));
}
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> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 28, i32 31, i32 poison, i32 poison>
+ %2 = shufflevector <9 x i16> %1, <9 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 15>
+ ret <8 x i16> %2
+}
>From 9f387d8a200d1bcde34776d5281e01e8984f89e2 Mon Sep 17 00:00:00 2001
From: Min-Yih Hsu <min.hsu at sifive.com>
Date: Thu, 14 Aug 2025 16:02:20 -0700
Subject: [PATCH 2/2] fixup! [DAGCombine] Fix an incorrect folding of
extract_subvector
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index feb8f8556067b..d343b644e41cb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -26018,12 +26018,12 @@ 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) &&
- // The index has to be a multiple of the new result type's known minimum
- // vector length.
- V.getConstantOperandVal(1) % NVT.getVectorMinNumElements() == 0) {
+ TLI.isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, NVT)) {
return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, NVT, V.getOperand(0),
V.getOperand(1));
}
More information about the llvm-commits
mailing list