[llvm] [DAGCombiner] Mark vectors as not AllAddOne/AllSubOne on type mismatch (PR #92195)
Patrick O'Neill via llvm-commits
llvm-commits at lists.llvm.org
Wed May 15 10:55:00 PDT 2024
https://github.com/patrick-rivos updated https://github.com/llvm/llvm-project/pull/92195
>From 9340008328a2341c024638c187ea0548627c26f1 Mon Sep 17 00:00:00 2001
From: Patrick O'Neill <patrick at rivosinc.com>
Date: Tue, 14 May 2024 16:41:24 -0700
Subject: [PATCH 1/3] [DAGCombiner] Mark vectors as not AllAddOne/AllSubOne on
undef or type mismatch
Fixes #92193.
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 +++++-
.../RISCV/dag-combine-vselect-datatype.ll | 42 +++++++++++++++++++
2 files changed, 52 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a044b6dc4838a..53519274f9fa6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12140,10 +12140,16 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
for (unsigned i = 0; i != Elts; ++i) {
SDValue N1Elt = N1.getOperand(i);
SDValue N2Elt = N2.getOperand(i);
- if (N1Elt.isUndef() || N2Elt.isUndef())
+ if (N1Elt.isUndef() || N2Elt.isUndef()) {
+ AllAddOne = false;
+ AllSubOne = false;
continue;
- if (N1Elt.getValueType() != N2Elt.getValueType())
+ }
+ if (N1Elt.getValueType() != N2Elt.getValueType()) {
+ AllAddOne = false;
+ AllSubOne = false;
continue;
+ }
const APInt &C1 = N1Elt->getAsAPIntVal();
const APInt &C2 = N2Elt->getAsAPIntVal();
@@ -12152,6 +12158,8 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
if (C1 != C2 - 1)
AllSubOne = false;
}
+ assert(!(AllAddOne && AllSubOne) &&
+ "Y=X+1 and Y=X-1 cannot be true for any given X and Y.");
// Further simplifications for the extra-special cases where the constants are
// all 0 or all -1 should be implemented as folds of these patterns.
diff --git a/llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll b/llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll
new file mode 100644
index 0000000000000..3a1dbd543546a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -O1 < %s | FileCheck %s
+
+; Dag-combine used to improperly combine a vector vselect of 0 and 5 into
+; 5 + condition(0/1) because one of the two args was transformed from an i32->i64.
+
+target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+target triple = "riscv64-unknown-linux-gnu"
+
+ at g.var.0 = global i8 5
+ at g.arr.0 = global i32 0
+
+define i8 @foo() {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lui a0, %hi(g.arr.0)
+; CHECK-NEXT: li a1, 4
+; CHECK-NEXT: sw a1, %lo(g.arr.0)(a0)
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+entry:
+ store i32 4, ptr @g.arr.0, align 32
+
+ %g.var.0.val = load i8, ptr @g.var.0, align 1
+ %loaded.arr = insertelement <4 x i8> <i8 1, i8 1, i8 1, i8 1>, i8 %g.var.0.val, i64 0
+
+ %g.arr.elem.0 = load i32, ptr @g.arr.0, align 32
+ %insert.0 = insertelement <4 x i32> zeroinitializer, i32 %g.arr.elem.0, i64 0
+ %cmp.0 = icmp ult <4 x i32> %insert.0, <i32 1, i32 1, i32 1, i32 1>
+
+ %all.g.arr.elem.0 = shufflevector <4 x i32> %insert.0, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
+ %or.0 = or <4 x i32> %all.g.arr.elem.0, <i32 1, i32 1, i32 1, i32 1>
+
+ %sel.0 = select <4 x i1> %cmp.0, <4 x i32> zeroinitializer, <4 x i32> %or.0
+
+ %trunc.0 = trunc <4 x i32> %sel.0 to <4 x i8>
+
+ %mul.0 = mul <4 x i8> %loaded.arr, %trunc.0
+ %reduced.mul.0 = call i8 @llvm.vector.reduce.mul.v4i8(<4 x i8> %mul.0)
+
+ ret i8 %reduced.mul.0
+}
>From 064a0840f0150efd89a9902e679d745fb859aaa7 Mon Sep 17 00:00:00 2001
From: Patrick O'Neill <patrick at rivosinc.com>
Date: Tue, 14 May 2024 19:26:03 -0700
Subject: [PATCH 2/3] fixup! [DAGCombiner] Mark vectors as not
AllAddOne/AllSubOne on undef or type mismatch
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 53519274f9fa6..2b181cd3ab1db 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12140,15 +12140,12 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
for (unsigned i = 0; i != Elts; ++i) {
SDValue N1Elt = N1.getOperand(i);
SDValue N2Elt = N2.getOperand(i);
- if (N1Elt.isUndef() || N2Elt.isUndef()) {
- AllAddOne = false;
- AllSubOne = false;
+ if (N1Elt.isUndef() || N2Elt.isUndef())
continue;
- }
if (N1Elt.getValueType() != N2Elt.getValueType()) {
AllAddOne = false;
AllSubOne = false;
- continue;
+ break;
}
const APInt &C1 = N1Elt->getAsAPIntVal();
@@ -12158,8 +12155,6 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) {
if (C1 != C2 - 1)
AllSubOne = false;
}
- assert(!(AllAddOne && AllSubOne) &&
- "Y=X+1 and Y=X-1 cannot be true for any given X and Y.");
// Further simplifications for the extra-special cases where the constants are
// all 0 or all -1 should be implemented as folds of these patterns.
>From 46104b694414a048c8462a83ac764e8f78a7bd68 Mon Sep 17 00:00:00 2001
From: Patrick O'Neill <patrick at rivosinc.com>
Date: Wed, 15 May 2024 10:52:27 -0700
Subject: [PATCH 3/3] fixup! [DAGCombiner] Mark vectors as not
AllAddOne/AllSubOne on undef or type mismatch
---
.../RISCV/dag-combine-vselect-datatype.ll | 42 -------------------
llvm/test/CodeGen/RISCV/pr92193.ll | 21 ++++++++++
2 files changed, 21 insertions(+), 42 deletions(-)
delete mode 100644 llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll
create mode 100644 llvm/test/CodeGen/RISCV/pr92193.ll
diff --git a/llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll b/llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll
deleted file mode 100644
index 3a1dbd543546a..0000000000000
--- a/llvm/test/CodeGen/RISCV/dag-combine-vselect-datatype.ll
+++ /dev/null
@@ -1,42 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -O1 < %s | FileCheck %s
-
-; Dag-combine used to improperly combine a vector vselect of 0 and 5 into
-; 5 + condition(0/1) because one of the two args was transformed from an i32->i64.
-
-target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
-target triple = "riscv64-unknown-linux-gnu"
-
- at g.var.0 = global i8 5
- at g.arr.0 = global i32 0
-
-define i8 @foo() {
-; CHECK-LABEL: foo:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(g.arr.0)
-; CHECK-NEXT: li a1, 4
-; CHECK-NEXT: sw a1, %lo(g.arr.0)(a0)
-; CHECK-NEXT: li a0, 0
-; CHECK-NEXT: ret
-entry:
- store i32 4, ptr @g.arr.0, align 32
-
- %g.var.0.val = load i8, ptr @g.var.0, align 1
- %loaded.arr = insertelement <4 x i8> <i8 1, i8 1, i8 1, i8 1>, i8 %g.var.0.val, i64 0
-
- %g.arr.elem.0 = load i32, ptr @g.arr.0, align 32
- %insert.0 = insertelement <4 x i32> zeroinitializer, i32 %g.arr.elem.0, i64 0
- %cmp.0 = icmp ult <4 x i32> %insert.0, <i32 1, i32 1, i32 1, i32 1>
-
- %all.g.arr.elem.0 = shufflevector <4 x i32> %insert.0, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
- %or.0 = or <4 x i32> %all.g.arr.elem.0, <i32 1, i32 1, i32 1, i32 1>
-
- %sel.0 = select <4 x i1> %cmp.0, <4 x i32> zeroinitializer, <4 x i32> %or.0
-
- %trunc.0 = trunc <4 x i32> %sel.0 to <4 x i8>
-
- %mul.0 = mul <4 x i8> %loaded.arr, %trunc.0
- %reduced.mul.0 = call i8 @llvm.vector.reduce.mul.v4i8(<4 x i8> %mul.0)
-
- ret i8 %reduced.mul.0
-}
diff --git a/llvm/test/CodeGen/RISCV/pr92193.ll b/llvm/test/CodeGen/RISCV/pr92193.ll
new file mode 100644
index 0000000000000..8c8398c4b45fa
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/pr92193.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=riscv64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -mtriple=riscv32-unknown-linux-gnu < %s | FileCheck %s
+
+; Dag-combine used to improperly combine a vector vselect of 0 and 2 into
+; 2 + condition(0/1) because one of the two args was transformed from an i32->i64.
+
+define i16 @foo() {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: ret
+entry:
+ %insert.0 = insertelement <4 x i16> zeroinitializer, i16 2, i64 0
+ %all.two = shufflevector <4 x i16> %insert.0, <4 x i16> zeroinitializer, <4 x i32> zeroinitializer
+ %sel.0 = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i16> zeroinitializer, <4 x i16> %all.two
+ %mul.0 = call i16 @llvm.vector.reduce.mul.v4i16(<4 x i16> %sel.0)
+ ret i16 %mul.0
+}
+
+declare i16 @llvm.vector.reduce.mul.v4i32(<4 x i16>)
More information about the llvm-commits
mailing list