-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[DAGCombine] Fix an incorrect folding of extract_subvector #153709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DAGCombine] Fix an incorrect folding of extract_subvector #153709
Conversation
|
@llvm/pr-subscribers-backend-risc-v Author: Min-Yih Hsu (mshockwave) ChangesReported from #153393 (comment) During DAGCombine, an intermediate extract_subvector sequence was generated: And one of the DAGCombine rule which turns This patch fixes this by adding an additional check. Full diff: https://github.com/llvm/llvm-project/pull/153709.diff 2 Files Affected:
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
+}
|
|
@llvm/pr-subscribers-llvm-selectiondag Author: Min-Yih Hsu (mshockwave) ChangesReported from #153393 (comment) During DAGCombine, an intermediate extract_subvector sequence was generated: And one of the DAGCombine rule which turns This patch fixes this by adding an additional check. Full diff: https://github.com/llvm/llvm-project/pull/153709.diff 2 Files Affected:
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
+}
|
| 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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall this be checked before checking isExtractSubvectorCheap?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yeah that'll be better, it's fixed now.
| ; CHECK-NEXT: vand.vv v8, v8, v9 | ||
| ; CHECK-NEXT: ret | ||
| entry: | ||
| %0 = load <19 x i16>, ptr null, align 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this pointer not null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed retroactively in 0f64ec8
The snippet was originally from llvm-reduce but we probably shouldn't use a null pointer in the actual test case. NFC.
Reported from #153393 (comment)
During DAGCombine, an intermediate extract_subvector sequence was generated:
And one of the DAGCombine rule which turns
(extract_subvector (extract_subvector X, C), 0)into(extract_subvector X, C)kicked in and turn that intov8i16 = extract_subvector t3, Constant:i64<9>. But it forgot to check if the extracted index is a multiple of the minimum vector length of the result type, hence the crash.This patch fixes this by adding an additional check.