[clang] [llvm] [mlir] [DAG] Refactor Undef/Poison queries to use UndefPoisonKind enum. (PR #195508)
via cfe-commits
cfe-commits at lists.llvm.org
Sun May 3 01:13:57 PDT 2026
https://github.com/levi42x created https://github.com/llvm/llvm-project/pull/195508
fixes : #194818
### Summary
This patch unifies the representation of undefined values across the compiler by migrating `SelectionDAG` from a `bool PoisonOnly` flag to the `UndefPoisonKind enum`.
- Moved _UndefPoisonKind_ to `llvm/Support/UndefPoisonKind.h` to provide a single source of truth for Middle-end, SelectionDAG, and GlobalISel.
- Replaced boolean flags in `isGuaranteedNotToBeUndefOrPoison` and `canCreateUndefOrPoison` with the enum to allow granular tracking of undef and poison states.
- Updated TargetLowering and architecture-specific implementations (including X86 and AArch64) to support the new enum-based callbacks.
>From e5ff73d0b932674d5c9969465a6b859ad4d214d4 Mon Sep 17 00:00:00 2001
From: shekhar suman <shekharsuman0397 at gmail.com>
Date: Tue, 3 Mar 2026 00:37:14 +0530
Subject: [PATCH 1/4] Address review: migrate OR to IR tests and fix
DemandedElts
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 +--
llvm/test/CodeGen/X86/known-never-zero.ll | 27 ++++++++++---------
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b33a1aaf65181..4cf09f1404e92 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6242,8 +6242,8 @@ bool SelectionDAG::isKnownNeverZero(SDValue Op, const APInt &DemandedElts,
}
case ISD::OR:
- return isKnownNeverZero(Op.getOperand(1), Depth + 1) ||
- isKnownNeverZero(Op.getOperand(0), Depth + 1);
+ return isKnownNeverZero(Op.getOperand(1), DemandedElts, Depth + 1) ||
+ isKnownNeverZero(Op.getOperand(0), DemandedElts, Depth + 1);
case ISD::VSELECT:
case ISD::SELECT:
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index a6b47bb7ae5d8..c1caf68b7cc20 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -434,18 +434,15 @@ define i32 @uaddsat_known_nonzero_vec(<16 x i8> %x, ptr %p) {
; X86-NEXT: paddusb {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: movzbl (%eax), %eax
-; X86-NEXT: bsfl %eax, %ecx
-; X86-NEXT: movl $32, %eax
-; X86-NEXT: cmovnel %ecx, %eax
+; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: uaddsat_known_nonzero_vec:
; X64: # %bb.0:
; X64-NEXT: vpaddusb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vpextrb $0, %xmm0, %ecx
-; X64-NEXT: movl $32, %eax
-; X64-NEXT: rep bsfl %ecx, %eax
+; X64-NEXT: vpextrb $0, %xmm0, %eax
+; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%z = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %x, <16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
store <16 x i8> %z, ptr %p
@@ -1227,7 +1224,9 @@ define i32 @sra_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X86-NEXT: psrad %xmm1, %xmm0
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: rep bsfl %eax, %eax
+; X86-NEXT: bsfl %eax, %ecx
+; X86-NEXT: movl $32, %eax
+; X86-NEXT: cmovnel %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: sra_known_nonzero_sign_bit_set_vec:
@@ -1236,8 +1235,9 @@ define i32 @sra_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X64-NEXT: vmovdqa {{.*#+}} xmm1 = [2147606891,65535,1,0]
; X64-NEXT: vpsrad %xmm0, %xmm1, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vmovd %xmm0, %eax
-; X64-NEXT: rep bsfl %eax, %eax
+; X64-NEXT: vmovd %xmm0, %ecx
+; X64-NEXT: movl $32, %eax
+; X64-NEXT: rep bsfl %ecx, %eax
; X64-NEXT: retq
%xx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
%z = ashr <4 x i32> <i32 2147606891, i32 65535, i32 1, i32 0>, %xx
@@ -1363,7 +1363,9 @@ define i32 @srl_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: rep bsfl %eax, %eax
+; X86-NEXT: bsfl %eax, %ecx
+; X86-NEXT: movl $32, %eax
+; X86-NEXT: cmovnel %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: srl_known_nonzero_sign_bit_set_vec:
@@ -1372,8 +1374,9 @@ define i32 @srl_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X64-NEXT: vmovdqa {{.*#+}} xmm1 = [0,65535,2147606891,0]
; X64-NEXT: vpsrld %xmm0, %xmm1, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vpextrd $2, %xmm0, %eax
-; X64-NEXT: rep bsfl %eax, %eax
+; X64-NEXT: vpextrd $2, %xmm0, %ecx
+; X64-NEXT: movl $32, %eax
+; X64-NEXT: rep bsfl %ecx, %eax
; X64-NEXT: retq
%x.splat = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
%z = lshr <4 x i32> <i32 0, i32 65535, i32 2147606891, i32 0>, %x.splat
>From e693b539a36cadd112ab0d21233cdd2c39aa8047 Mon Sep 17 00:00:00 2001
From: shekhar suman <shekharsuman0397 at gmail.com>
Date: Tue, 3 Mar 2026 03:49:42 +0530
Subject: [PATCH 2/4] update branch and regenrate test file
---
llvm/test/CodeGen/X86/known-never-zero.ll | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index 593d193679e16..b11ea734b8e9b 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -1969,8 +1969,9 @@ define i32 @test_zext_demanded_elts(<4 x i32> %a0, ptr %p) {
; X64-NEXT: vunpckhps {{.*#+}} xmm2 = xmm0[2],xmm2[2],xmm0[3],xmm2[3]
; X64-NEXT: vmovaps %xmm2, 16(%rdi)
; X64-NEXT: vmovdqa %xmm1, (%rdi)
-; X64-NEXT: vmovd %xmm0, %eax
-; X64-NEXT: rep bsfq %rax, %rax
+; X64-NEXT: vmovd %xmm0, %ecx
+; X64-NEXT: movl $64, %eax
+; X64-NEXT: rep bsfq %rcx, %rax
; X64-NEXT: # kill: def $eax killed $eax killed $rax
; X64-NEXT: retq
%cmp = icmp sgt <4 x i32> zeroinitializer, %a0
@@ -2003,11 +2004,12 @@ define i32 @test_sext_demanded_elts(<4 x i32> %a0, ptr %p) {
; X86-NEXT: movdqa %xmm0, 16(%eax)
; X86-NEXT: movdqa %xmm2, (%eax)
; X86-NEXT: movd %xmm1, %eax
-; X86-NEXT: rep bsfl %ecx, %edx
-; X86-NEXT: rep bsfl %eax, %eax
-; X86-NEXT: addl $32, %eax
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: cmovnel %edx, %eax
+; X86-NEXT: bsfl %eax, %eax
+; X86-NEXT: movl $32, %edx
+; X86-NEXT: cmovnel %eax, %edx
+; X86-NEXT: addl $32, %edx
+; X86-NEXT: bsfl %ecx, %eax
+; X86-NEXT: cmovel %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_sext_demanded_elts:
@@ -2019,8 +2021,9 @@ define i32 @test_sext_demanded_elts(<4 x i32> %a0, ptr %p) {
; X64-NEXT: vpmovsxdq %xmm0, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
; X64-NEXT: vmovdqa %xmm1, 16(%rdi)
-; X64-NEXT: vmovq %xmm0, %rax
-; X64-NEXT: rep bsfq %rax, %rax
+; X64-NEXT: vmovq %xmm0, %rcx
+; X64-NEXT: movl $64, %eax
+; X64-NEXT: rep bsfq %rcx, %rax
; X64-NEXT: # kill: def $eax killed $eax killed $rax
; X64-NEXT: retq
%cmp = icmp sgt <4 x i32> zeroinitializer, %a0
>From c6e4a6b97d5906cf138b2ab0c6bdf32b811232dc Mon Sep 17 00:00:00 2001
From: shekhar suman <shekharsuman0397 at gmail.com>
Date: Tue, 3 Mar 2026 16:04:12 +0530
Subject: [PATCH 3/4] regenerate known-never-zero.ll
---
llvm/test/CodeGen/X86/known-never-zero.ll | 75 +++++++++--------------
1 file changed, 30 insertions(+), 45 deletions(-)
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index b11ea734b8e9b..144123486b08f 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -31,18 +31,15 @@ define i32 @or_known_nonzero_vec(<4 x i32> %x, ptr %p) {
; X86-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: bsfl %eax, %ecx
-; X86-NEXT: movl $32, %eax
-; X86-NEXT: cmovnel %ecx, %eax
+; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: or_known_nonzero_vec:
; X64: # %bb.0:
; X64-NEXT: vpor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vmovd %xmm0, %ecx
-; X64-NEXT: movl $32, %eax
-; X64-NEXT: rep bsfl %ecx, %eax
+; X64-NEXT: vmovd %xmm0, %eax
+; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%z = or <4 x i32> %x, <i32 1, i32 0, i32 0, i32 0>
store <4 x i32> %z, ptr %p
@@ -434,15 +431,18 @@ define i32 @uaddsat_known_nonzero_vec(<16 x i8> %x, ptr %p) {
; X86-NEXT: paddusb {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: movzbl (%eax), %eax
-; X86-NEXT: rep bsfl %eax, %eax
+; X86-NEXT: bsfl %eax, %ecx
+; X86-NEXT: movl $32, %eax
+; X86-NEXT: cmovnel %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: uaddsat_known_nonzero_vec:
; X64: # %bb.0:
; X64-NEXT: vpaddusb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vpextrb $0, %xmm0, %eax
-; X64-NEXT: rep bsfl %eax, %eax
+; X64-NEXT: vpextrb $0, %xmm0, %ecx
+; X64-NEXT: movl $32, %eax
+; X64-NEXT: rep bsfl %ecx, %eax
; X64-NEXT: retq
%z = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %x, <16 x i8> <i8 1, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>)
store <16 x i8> %z, ptr %p
@@ -1224,9 +1224,7 @@ define i32 @sra_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X86-NEXT: psrad %xmm1, %xmm0
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: bsfl %eax, %ecx
-; X86-NEXT: movl $32, %eax
-; X86-NEXT: cmovnel %ecx, %eax
+; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: sra_known_nonzero_sign_bit_set_vec:
@@ -1235,9 +1233,8 @@ define i32 @sra_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X64-NEXT: vmovdqa {{.*#+}} xmm1 = [2147606891,65535,1,0]
; X64-NEXT: vpsrad %xmm0, %xmm1, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vmovd %xmm0, %ecx
-; X64-NEXT: movl $32, %eax
-; X64-NEXT: rep bsfl %ecx, %eax
+; X64-NEXT: vmovd %xmm0, %eax
+; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%xx = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
%z = ashr <4 x i32> <i32 2147606891, i32 65535, i32 1, i32 0>, %xx
@@ -1282,9 +1279,7 @@ define i32 @sra_known_nonzero_exact_vec(<4 x i32> %x, <4 x i32> %yy, ptr %p) {
; X86-NEXT: movdqa %xmm1, (%eax)
; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: bsfl %eax, %ecx
-; X86-NEXT: movl $32, %eax
-; X86-NEXT: cmovnel %ecx, %eax
+; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: sra_known_nonzero_exact_vec:
@@ -1293,9 +1288,8 @@ define i32 @sra_known_nonzero_exact_vec(<4 x i32> %x, <4 x i32> %yy, ptr %p) {
; X64-NEXT: vpor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
; X64-NEXT: vpsrad %xmm0, %xmm1, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vpextrd $1, %xmm0, %ecx
-; X64-NEXT: movl $32, %eax
-; X64-NEXT: rep bsfl %ecx, %eax
+; X64-NEXT: vpextrd $1, %xmm0, %eax
+; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x.splat = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
%y = or <4 x i32> %yy, <i32 0, i32 256, i32 0, i32 0>
@@ -1363,9 +1357,7 @@ define i32 @srl_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X86-NEXT: movdqa %xmm0, (%eax)
; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: bsfl %eax, %ecx
-; X86-NEXT: movl $32, %eax
-; X86-NEXT: cmovnel %ecx, %eax
+; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: srl_known_nonzero_sign_bit_set_vec:
@@ -1374,9 +1366,8 @@ define i32 @srl_known_nonzero_sign_bit_set_vec(<4 x i32> %x, ptr %p) {
; X64-NEXT: vmovdqa {{.*#+}} xmm1 = [0,65535,2147606891,0]
; X64-NEXT: vpsrld %xmm0, %xmm1, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vpextrd $2, %xmm0, %ecx
-; X64-NEXT: movl $32, %eax
-; X64-NEXT: rep bsfl %ecx, %eax
+; X64-NEXT: vpextrd $2, %xmm0, %eax
+; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x.splat = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
%z = lshr <4 x i32> <i32 0, i32 65535, i32 2147606891, i32 0>, %x.splat
@@ -1421,9 +1412,7 @@ define i32 @srl_known_nonzero_exact_vec(<4 x i32> %x, <4 x i32> %yy, ptr %p) {
; X86-NEXT: movdqa %xmm1, (%eax)
; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm1[3,3,3,3]
; X86-NEXT: movd %xmm0, %eax
-; X86-NEXT: bsfl %eax, %ecx
-; X86-NEXT: movl $32, %eax
-; X86-NEXT: cmovnel %ecx, %eax
+; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: srl_known_nonzero_exact_vec:
@@ -1432,9 +1421,8 @@ define i32 @srl_known_nonzero_exact_vec(<4 x i32> %x, <4 x i32> %yy, ptr %p) {
; X64-NEXT: vpor {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
; X64-NEXT: vpsrld %xmm0, %xmm1, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
-; X64-NEXT: vpextrd $3, %xmm0, %ecx
-; X64-NEXT: movl $32, %eax
-; X64-NEXT: rep bsfl %ecx, %eax
+; X64-NEXT: vpextrd $3, %xmm0, %eax
+; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x.splat = shufflevector <4 x i32> %x, <4 x i32> poison, <4 x i32> zeroinitializer
%y = or <4 x i32> %yy, <i32 0, i32 0, i32 0, i32 256>
@@ -1969,9 +1957,8 @@ define i32 @test_zext_demanded_elts(<4 x i32> %a0, ptr %p) {
; X64-NEXT: vunpckhps {{.*#+}} xmm2 = xmm0[2],xmm2[2],xmm0[3],xmm2[3]
; X64-NEXT: vmovaps %xmm2, 16(%rdi)
; X64-NEXT: vmovdqa %xmm1, (%rdi)
-; X64-NEXT: vmovd %xmm0, %ecx
-; X64-NEXT: movl $64, %eax
-; X64-NEXT: rep bsfq %rcx, %rax
+; X64-NEXT: vmovd %xmm0, %eax
+; X64-NEXT: rep bsfq %rax, %rax
; X64-NEXT: # kill: def $eax killed $eax killed $rax
; X64-NEXT: retq
%cmp = icmp sgt <4 x i32> zeroinitializer, %a0
@@ -2004,12 +1991,11 @@ define i32 @test_sext_demanded_elts(<4 x i32> %a0, ptr %p) {
; X86-NEXT: movdqa %xmm0, 16(%eax)
; X86-NEXT: movdqa %xmm2, (%eax)
; X86-NEXT: movd %xmm1, %eax
-; X86-NEXT: bsfl %eax, %eax
-; X86-NEXT: movl $32, %edx
-; X86-NEXT: cmovnel %eax, %edx
-; X86-NEXT: addl $32, %edx
-; X86-NEXT: bsfl %ecx, %eax
-; X86-NEXT: cmovel %edx, %eax
+; X86-NEXT: rep bsfl %ecx, %edx
+; X86-NEXT: rep bsfl %eax, %eax
+; X86-NEXT: addl $32, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: cmovnel %edx, %eax
; X86-NEXT: retl
;
; X64-LABEL: test_sext_demanded_elts:
@@ -2021,9 +2007,8 @@ define i32 @test_sext_demanded_elts(<4 x i32> %a0, ptr %p) {
; X64-NEXT: vpmovsxdq %xmm0, %xmm0
; X64-NEXT: vmovdqa %xmm0, (%rdi)
; X64-NEXT: vmovdqa %xmm1, 16(%rdi)
-; X64-NEXT: vmovq %xmm0, %rcx
-; X64-NEXT: movl $64, %eax
-; X64-NEXT: rep bsfq %rcx, %rax
+; X64-NEXT: vmovq %xmm0, %rax
+; X64-NEXT: rep bsfq %rax, %rax
; X64-NEXT: # kill: def $eax killed $eax killed $rax
; X64-NEXT: retq
%cmp = icmp sgt <4 x i32> zeroinitializer, %a0
>From 405b205ee542c53eea9c9f683a209968094426a2 Mon Sep 17 00:00:00 2001
From: shekhar suman <shekharsuman0397 at gmail.com>
Date: Sun, 3 May 2026 13:04:18 +0530
Subject: [PATCH 4/4] [DAG] Refactor Undef/Poison queries to use
UndefPoisonKind enum
---
clang/lib/Serialization/ASTWriter.cpp | 3 +-
llvm/include/llvm/CodeGen/SelectionDAG.h | 65 +++----
llvm/include/llvm/CodeGen/TargetLowering.h | 10 +-
llvm/include/llvm/Support/UndefPoisonKind.h | 16 ++
llvm/lib/Analysis/ValueTracking.cpp | 24 ++-
llvm/lib/CodeGen/GlobalISel/Utils.cpp | 9 +-
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 +-
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 160 ++++++++----------
.../CodeGen/SelectionDAG/TargetLowering.cpp | 14 +-
.../Target/AArch64/AArch64ISelLowering.cpp | 4 +-
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 8 +-
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 4 +-
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h | 8 +-
llvm/lib/Target/ARM/ARMISelLowering.cpp | 4 +-
llvm/lib/Target/ARM/ARMISelLowering.h | 9 +-
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 +-
llvm/lib/Target/RISCV/RISCVISelLowering.h | 8 +-
.../Target/SystemZ/SystemZISelLowering.cpp | 7 +-
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 2 +-
llvm/lib/Target/X86/X86ISelLowering.cpp | 18 +-
llvm/lib/Target/X86/X86ISelLowering.h | 11 +-
.../Linalg/TransformOps/LinalgTransformOps.td | 8 +-
.../mlir/Dialect/OpenACC/OpenACCCGOps.td | 16 +-
.../mlir/Dialect/OpenACC/OpenACCOps.td | 11 +-
.../mlir/Dialect/OpenACC/Transforms/Passes.td | 9 +-
25 files changed, 221 insertions(+), 223 deletions(-)
create mode 100644 llvm/include/llvm/Support/UndefPoisonKind.h
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 2d0f257d02d6d..814f4e42e9c9b 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7825,7 +7825,8 @@ void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
}
void ASTWriter::DeclarationMarkedOpenMPIndirectCall(const Decl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
+ if (Chain && Chain->isProcessingUpdateRecords())
+ return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
return;
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index b2a9e076fb90e..a51ba211b407c 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -41,6 +41,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/RecyclingAllocator.h"
+#include "llvm/Support/UndefPoisonKind.h"
#include <cassert>
#include <cstdint>
#include <functional>
@@ -1770,9 +1771,10 @@ class SelectionDAG {
LLVM_ABI SDValue getFreeze(SDValue V);
/// Return a freeze of V if any of the demanded elts may be undef or poison.
- /// If \p PoisonOnly is true, then only check for poison elements.
- LLVM_ABI SDValue getFreeze(SDValue V, const APInt &DemandedElts,
- bool PoisonOnly = false);
+ /// The Kind argument specifies whether to check for undef, poison, or both.
+ LLVM_ABI SDValue
+ getFreeze(SDValue V, const APInt &DemandedElts,
+ UndefPoisonKind Kind = UndefPoisonKind::UndefOrPoison);
/// Return an AssertAlignSDNode.
LLVM_ABI SDValue getAssertAlign(const SDLoc &DL, SDValue V, Align A);
@@ -2303,22 +2305,23 @@ class SelectionDAG {
unsigned Depth = 0) const;
/// Return true if this function can prove that \p Op is never poison
- /// and, if \p PoisonOnly is false, does not have undef bits.
- LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(SDValue Op,
- bool PoisonOnly = false,
- unsigned Depth = 0) const;
+ /// and, if \p Kind includes undef, does not have undef bits.
+ LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(
+ SDValue Op, UndefPoisonKind Kind = UndefPoisonKind::UndefOrPoison,
+ unsigned Depth = 0) const;
/// Return true if this function can prove that \p Op is never poison
- /// and, if \p PoisonOnly is false, does not have undef bits. The DemandedElts
+ /// and, if \p Kind includes undef, does not have undef bits. The DemandedElts
/// argument limits the check to the requested vector elements.
- LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(SDValue Op,
- const APInt &DemandedElts,
- bool PoisonOnly = false,
- unsigned Depth = 0) const;
+ LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(
+ SDValue Op, const APInt &DemandedElts,
+ UndefPoisonKind Kind = UndefPoisonKind::UndefOrPoison,
+ unsigned Depth = 0) const;
/// Return true if this function can prove that \p Op is never poison.
bool isGuaranteedNotToBePoison(SDValue Op, unsigned Depth = 0) const {
- return isGuaranteedNotToBeUndefOrPoison(Op, /*PoisonOnly*/ true, Depth);
+ return isGuaranteedNotToBeUndefOrPoison(Op, UndefPoisonKind::PoisonOnly,
+ Depth);
}
/// Return true if this function can prove that \p Op is never poison. The
@@ -2326,35 +2329,35 @@ class SelectionDAG {
bool isGuaranteedNotToBePoison(SDValue Op, const APInt &DemandedElts,
unsigned Depth = 0) const {
return isGuaranteedNotToBeUndefOrPoison(Op, DemandedElts,
- /*PoisonOnly*/ true, Depth);
+ UndefPoisonKind::PoisonOnly, Depth);
}
/// Return true if Op can create undef or poison from non-undef & non-poison
- /// operands. The DemandedElts argument limits the check to the requested
- /// vector elements.
+ /// operands based on the types specified in \p Kind. The DemandedElts
+ /// argument limits the check to the requested vector elements.
///
/// \p ConsiderFlags controls whether poison producing flags on the
- /// instruction are considered. This can be used to see if the instruction
+ /// instruction are considered. This can be used to see if the instruction
/// could still introduce undef or poison even without poison generating flags
- /// which might be on the instruction. (i.e. could the result of
- /// Op->dropPoisonGeneratingFlags() still create poison or undef)
- LLVM_ABI bool canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
- bool PoisonOnly = false,
- bool ConsiderFlags = true,
- unsigned Depth = 0) const;
+ /// which might be on the instruction (i.e., could the result of
+ /// Op->dropPoisonGeneratingFlags() still create poison or undef).
+ LLVM_ABI bool
+ canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
+ UndefPoisonKind Kind = UndefPoisonKind::UndefOrPoison,
+ bool ConsiderFlags = true, unsigned Depth = 0) const;
/// Return true if Op can create undef or poison from non-undef & non-poison
- /// operands.
+ /// operands based on the types specified in \p Kind.
///
/// \p ConsiderFlags controls whether poison producing flags on the
- /// instruction are considered. This can be used to see if the instruction
+ /// instruction are considered. This can be used to see if the instruction
/// could still introduce undef or poison even without poison generating flags
- /// which might be on the instruction. (i.e. could the result of
- /// Op->dropPoisonGeneratingFlags() still create poison or undef)
- LLVM_ABI bool canCreateUndefOrPoison(SDValue Op, bool PoisonOnly = false,
- bool ConsiderFlags = true,
- unsigned Depth = 0) const;
-
+ /// which might be on the instruction (i.e., could the result of
+ /// Op->dropPoisonGeneratingFlags() still create poison or undef).
+ LLVM_ABI bool
+ canCreateUndefOrPoison(SDValue Op,
+ UndefPoisonKind Kind = UndefPoisonKind::UndefOrPoison,
+ bool ConsiderFlags = true, unsigned Depth = 0) const;
/// Return true if the specified operand is an ISD::OR or ISD::XOR node
/// that can be treated as an ISD::ADD node.
/// or(x,y) == add(x,y) iff haveNoCommonBitsSet(x,y)
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 4b60c3f905120..ff4719d8c06f0 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -54,6 +54,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownFPClass.h"
+#include "llvm/Support/UndefPoisonKind.h"
#include <algorithm>
#include <cassert>
#include <climits>
@@ -4407,15 +4408,14 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
/// argument limits the check to the requested vector elements.
virtual bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, unsigned Depth) const;
+ UndefPoisonKind Kind, unsigned Depth) const;
/// Return true if Op can create undef or poison from non-undef & non-poison
/// operands. The DemandedElts argument limits the check to the requested
/// vector elements.
- virtual bool
- canCreateUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts,
- const SelectionDAG &DAG, bool PoisonOnly,
- bool ConsiderFlags, unsigned Depth) const;
+ virtual bool canCreateUndefOrPoisonForTargetNode(
+ SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const;
/// Tries to build a legal vector shuffle using the provided parameters
/// or equivalent variations. The Mask argument maybe be modified as the
diff --git a/llvm/include/llvm/Support/UndefPoisonKind.h b/llvm/include/llvm/Support/UndefPoisonKind.h
new file mode 100644
index 0000000000000..ec906f80ed185
--- /dev/null
+++ b/llvm/include/llvm/Support/UndefPoisonKind.h
@@ -0,0 +1,16 @@
+#ifndef LLVM_SUPPORT_UNDEFPOISONKIND_H
+#define LLVM_SUPPORT_UNDEFPOISONKIND_H
+
+namespace llvm {
+
+/// Enumeration of the different types of "undefined" values in LLVM.
+enum class UndefPoisonKind {
+ PoisonOnly = (1 << 0),
+ UndefOnly = (1 << 1),
+ UndefOrPoison = PoisonOnly | UndefOnly,
+ LLVM_MARK_AS_BITMASK_ENUM(UndefOrPoison)
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_UNDEFPOISONKIND_H
\ No newline at end of file
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3ddbc3bce804a..ba03a21068780 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -75,6 +75,7 @@
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/KnownFPClass.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/UndefPoisonKind.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
#include <algorithm>
#include <cassert>
@@ -7535,12 +7536,6 @@ static bool shiftAmountKnownInRange(const Value *ShiftAmount) {
return Safe;
}
-enum class UndefPoisonKind {
- PoisonOnly = (1 << 0),
- UndefOnly = (1 << 1),
- UndefOrPoison = PoisonOnly | UndefOnly,
-};
-
static bool includesPoison(UndefPoisonKind Kind) {
return (unsigned(Kind) & unsigned(UndefPoisonKind::PoisonOnly)) != 0;
}
@@ -7698,7 +7693,8 @@ bool llvm::impliesPoison(const Value *ValAssumedPoison, const Value *V) {
return ::impliesPoison(ValAssumedPoison, V, /* Depth */ 0);
}
-static bool programUndefinedIfUndefOrPoison(const Value *V, bool PoisonOnly);
+static bool programUndefinedIfUndefOrPoison(const Value *V,
+ UndefPoisonKind Kind);
static bool isGuaranteedNotToBeUndefOrPoison(
const Value *V, AssumptionCache *AC, const Instruction *CtxI,
@@ -7806,7 +7802,9 @@ static bool isGuaranteedNotToBeUndefOrPoison(
I->hasMetadata(LLVMContext::MD_dereferenceable_or_null))
return true;
- if (programUndefinedIfUndefOrPoison(V, !includesUndef(Kind)))
+ if (programUndefinedIfUndefOrPoison(V, includesUndef(Kind)
+ ? UndefPoisonKind::UndefOrPoison
+ : UndefPoisonKind::PoisonOnly))
return true;
// CxtI may be null or a cloned instruction.
@@ -8206,7 +8204,7 @@ bool llvm::mustTriggerUB(const Instruction *I,
}
static bool programUndefinedIfUndefOrPoison(const Value *V,
- bool PoisonOnly) {
+ UndefPoisonKind Kind) {
// We currently only look for uses of values within the same basic
// block, as that makes it easier to guarantee that the uses will be
// executed given that Inst is executed.
@@ -8234,7 +8232,7 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
unsigned ScanLimit = 32;
BasicBlock::const_iterator End = BB->end();
- if (!PoisonOnly) {
+ if (includesUndef(Kind)) {
// Since undef does not propagate eagerly, be conservative & just check
// whether a value is directly passed to an instruction that must take
// well-defined operands.
@@ -8298,13 +8296,13 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
}
return false;
}
-
bool llvm::programUndefinedIfUndefOrPoison(const Instruction *Inst) {
- return ::programUndefinedIfUndefOrPoison(Inst, false);
+ return ::programUndefinedIfUndefOrPoison(Inst,
+ UndefPoisonKind::UndefOrPoison);
}
bool llvm::programUndefinedIfPoison(const Instruction *Inst) {
- return ::programUndefinedIfUndefOrPoison(Inst, true);
+ return ::programUndefinedIfUndefOrPoison(Inst, UndefPoisonKind::PoisonOnly);
}
static bool isKnownNonNaN(const Value *V, FastMathFlags FMF) {
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index e3ec021085a29..59a4f21293318 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -33,6 +33,7 @@
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/Constants.h"
+#include "llvm/Support/UndefPoisonKind.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/SizeOpts.h"
#include <numeric>
@@ -1833,14 +1834,6 @@ static bool shiftAmountKnownInRange(Register ShiftAmount,
return true;
}
-namespace {
-enum class UndefPoisonKind {
- PoisonOnly = (1 << 0),
- UndefOnly = (1 << 1),
- UndefOrPoison = PoisonOnly | UndefOnly,
-};
-}
-
static bool includesPoison(UndefPoisonKind Kind) {
return (unsigned(Kind) & unsigned(UndefPoisonKind::PoisonOnly)) != 0;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a90b266308e9b..fdf056e766ee0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -64,6 +64,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/UndefPoisonKind.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@@ -17447,7 +17448,7 @@ SDValue DAGCombiner::visitBUILD_PAIR(SDNode *N) {
SDValue DAGCombiner::visitFREEZE(SDNode *N) {
SDValue N0 = N->getOperand(0);
- if (DAG.isGuaranteedNotToBeUndefOrPoison(N0, /*PoisonOnly*/ false))
+ if (DAG.isGuaranteedNotToBeUndefOrPoison(N0, UndefPoisonKind::UndefOrPoison))
return N0;
// If we have frozen and unfrozen users of N0, update so everything uses N.
@@ -17476,7 +17477,7 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
// guaranteed-non-poison operands (or is a BUILD_VECTOR or similar) then push
// the freeze through to the operands that are not guaranteed non-poison.
// NOTE: we will strip poison-generating flags, so ignore them here.
- if (DAG.canCreateUndefOrPoison(N0, /*PoisonOnly*/ false,
+ if (DAG.canCreateUndefOrPoison(N0, UndefPoisonKind::UndefOrPoison,
/*ConsiderFlags*/ false) ||
N0->getNumValues() != 1 || !N0->hasOneUse())
return SDValue();
@@ -17517,7 +17518,8 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
SmallSet<SDValue, 8> MaybePoisonOperands;
SmallVector<unsigned, 8> MaybePoisonOperandNumbers;
for (auto [OpNo, Op] : enumerate(N0->ops())) {
- if (DAG.isGuaranteedNotToBeUndefOrPoison(Op, /*PoisonOnly=*/false))
+ if (DAG.isGuaranteedNotToBeUndefOrPoison(Op,
+ UndefPoisonKind::UndefOrPoison))
continue;
bool HadMaybePoisonOperands = !MaybePoisonOperands.empty();
bool IsNewMaybePoisonOperand = MaybePoisonOperands.insert(Op).second;
@@ -24389,8 +24391,8 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) {
// Make sure to freeze the source vector in case any of the elements
// overwritten by the insert may be poison. Otherwise those elements
// could end up being poison instead of 0/-1 after the AND/OR.
- CurVec =
- DAG.getFreeze(CurVec, InsertedEltMask, /*PoisonOnly=*/true);
+ CurVec = DAG.getFreeze(CurVec, InsertedEltMask,
+ UndefPoisonKind::PoisonOnly);
return DAG.getNode(MaskOpcode, DL, VT, CurVec,
DAG.getBuildVector(VT, DL, Mask));
};
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 168d30c2789a8..733bce0b8c221 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2541,8 +2541,8 @@ SDValue SelectionDAG::getFreeze(SDValue V) {
}
SDValue SelectionDAG::getFreeze(SDValue V, const APInt &DemandedElts,
- bool PoisonOnly) {
- if (isGuaranteedNotToBeUndefOrPoison(V, DemandedElts, PoisonOnly))
+ UndefPoisonKind Kind) {
+ if (isGuaranteedNotToBeUndefOrPoison(V, DemandedElts, Kind))
return V;
return getFreeze(V);
}
@@ -3656,7 +3656,8 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
// TODO: SelfMultiply can be poison, but not undef.
if (SelfMultiply)
SelfMultiply &= isGuaranteedNotToBeUndefOrPoison(
- Op.getOperand(0), DemandedElts, false, Depth + 1);
+ Op.getOperand(0), DemandedElts, UndefPoisonKind::UndefOrPoison,
+ Depth + 1);
Known = KnownBits::mul(Known, Known2, SelfMultiply);
// If the multiplication is known not to overflow, the product of a number
@@ -4843,7 +4844,8 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
return VTBits-Tmp;
case ISD::FREEZE:
if (isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), DemandedElts,
- /*PoisonOnly=*/false))
+ UndefPoisonKind::UndefOrPoison,
+ Depth + 1))
return ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1);
break;
case ISD::MERGE_VALUES:
@@ -5517,7 +5519,8 @@ unsigned SelectionDAG::ComputeMaxSignificantBits(SDValue Op,
return Op.getScalarValueSizeInBits() - SignBits + 1;
}
-bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op, bool PoisonOnly,
+bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
+ UndefPoisonKind Kind,
unsigned Depth) const {
// Early out for FREEZE.
if (Op.getOpcode() == ISD::FREEZE)
@@ -5527,12 +5530,12 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op, bool PoisonOnly,
APInt DemandedElts = VT.isFixedLengthVector()
? APInt::getAllOnes(VT.getVectorNumElements())
: APInt(1, 1);
- return isGuaranteedNotToBeUndefOrPoison(Op, DemandedElts, PoisonOnly, Depth);
+ return isGuaranteedNotToBeUndefOrPoison(Op, DemandedElts, Kind, Depth);
}
bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
const APInt &DemandedElts,
- bool PoisonOnly,
+ UndefPoisonKind Kind,
unsigned Depth) const {
unsigned Opcode = Op.getOpcode();
@@ -5546,6 +5549,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
if (isIntOrFPConstant(Op))
return true;
+ bool IncludeUndef =
+ ((unsigned)Kind & (unsigned)UndefPoisonKind::UndefOnly) != 0;
+
switch (Opcode) {
case ISD::CONDCODE:
case ISD::VALUETYPE:
@@ -5558,16 +5564,15 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
return false;
case ISD::UNDEF:
- return PoisonOnly;
+ // If we are checking for Undef, then an UNDEF node is not guaranteed.
+ // If we are only checking for Poison, then an UNDEF node is guaranteed.
+ return !IncludeUndef;
case ISD::BUILD_VECTOR:
- // NOTE: BUILD_VECTOR has implicit truncation of wider scalar elements -
- // this shouldn't affect the result.
for (unsigned i = 0, e = Op.getNumOperands(); i < e; ++i) {
if (!DemandedElts[i])
continue;
- if (!isGuaranteedNotToBeUndefOrPoison(Op.getOperand(i), PoisonOnly,
- Depth + 1))
+ if (!isGuaranteedNotToBeUndefOrPoison(Op.getOperand(i), Kind, Depth + 1))
return false;
}
return true;
@@ -5579,7 +5584,7 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
uint64_t Idx = Op.getConstantOperandVal(1);
unsigned NumSrcElts = Src.getValueType().getVectorNumElements();
APInt DemandedSrcElts = DemandedElts.zext(NumSrcElts).shl(Idx);
- return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, PoisonOnly,
+ return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, Kind,
Depth + 1);
}
@@ -5595,10 +5600,10 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
DemandedSrcElts.clearBits(Idx, Idx + NumSubElts);
if (!!DemandedSubElts && !isGuaranteedNotToBeUndefOrPoison(
- Sub, DemandedSubElts, PoisonOnly, Depth + 1))
+ Sub, DemandedSubElts, Kind, Depth + 1))
return false;
if (!!DemandedSrcElts && !isGuaranteedNotToBeUndefOrPoison(
- Src, DemandedSrcElts, PoisonOnly, Depth + 1))
+ Src, DemandedSrcElts, Kind, Depth + 1))
return false;
return true;
}
@@ -5611,7 +5616,7 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
IndexC->getAPIntValue().ult(SrcVT.getVectorNumElements())) {
APInt DemandedSrcElts = APInt::getOneBitSet(SrcVT.getVectorNumElements(),
IndexC->getZExtValue());
- return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, PoisonOnly,
+ return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, Kind,
Depth + 1);
}
break;
@@ -5626,14 +5631,14 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
if (IndexC && VT.isFixedLengthVector() &&
IndexC->getAPIntValue().ult(VT.getVectorNumElements())) {
if (DemandedElts[IndexC->getZExtValue()] &&
- !isGuaranteedNotToBeUndefOrPoison(InVal, PoisonOnly, Depth + 1))
+ !isGuaranteedNotToBeUndefOrPoison(InVal, Kind, Depth + 1))
return false;
APInt InVecDemandedElts = DemandedElts;
InVecDemandedElts.clearBit(IndexC->getZExtValue());
if (!!InVecDemandedElts &&
!isGuaranteedNotToBeUndefOrPoison(
peekThroughInsertVectorElt(InVec, InVecDemandedElts),
- InVecDemandedElts, PoisonOnly, Depth + 1))
+ InVecDemandedElts, Kind, Depth + 1))
return false;
return true;
}
@@ -5642,17 +5647,16 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
case ISD::SCALAR_TO_VECTOR:
// Check upper (known undef) elements.
- if (DemandedElts.ugt(1) && !PoisonOnly)
+ if (DemandedElts.ugt(1) && IncludeUndef)
return false;
// Check element zero.
- if (DemandedElts[0] && !isGuaranteedNotToBeUndefOrPoison(
- Op.getOperand(0), PoisonOnly, Depth + 1))
+ if (DemandedElts[0] &&
+ !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), Kind, Depth + 1))
return false;
return true;
case ISD::SPLAT_VECTOR:
- return isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), PoisonOnly,
- Depth + 1);
+ return isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), Kind, Depth + 1);
case ISD::VECTOR_SHUFFLE: {
APInt DemandedLHS, DemandedRHS;
@@ -5662,12 +5666,12 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
/*AllowUndefElts=*/false))
return false;
if (!DemandedLHS.isZero() &&
- !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), DemandedLHS,
- PoisonOnly, Depth + 1))
+ !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), DemandedLHS, Kind,
+ Depth + 1))
return false;
if (!DemandedRHS.isZero() &&
- !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(1), DemandedRHS,
- PoisonOnly, Depth + 1))
+ !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(1), DemandedRHS, Kind,
+ Depth + 1))
return false;
return true;
}
@@ -5675,12 +5679,10 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
case ISD::SHL:
case ISD::SRL:
case ISD::SRA:
- // Shift amount operand is checked by canCreateUndefOrPoison. So it is
- // enough to check operand 0 if Op can't create undef/poison.
- return !canCreateUndefOrPoison(Op, DemandedElts, PoisonOnly,
+ return !canCreateUndefOrPoison(Op, DemandedElts, Kind,
/*ConsiderFlags*/ true, Depth) &&
isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), DemandedElts,
- PoisonOnly, Depth + 1);
+ Kind, Depth + 1);
case ISD::BSWAP:
case ISD::CTPOP:
@@ -5706,58 +5708,51 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
case ISD::ANY_EXTEND:
case ISD::TRUNCATE:
case ISD::VSELECT: {
- // If Op can't create undef/poison and none of its operands are undef/poison
- // then Op is never undef/poison. A difference from the more common check
- // below, outside the switch, is that we handle elementwise operations for
- // which the DemandedElts mask is valid for all operands here.
- return !canCreateUndefOrPoison(Op, DemandedElts, PoisonOnly,
+ return !canCreateUndefOrPoison(Op, DemandedElts, Kind,
/*ConsiderFlags*/ true, Depth) &&
all_of(Op->ops(), [&](SDValue V) {
- return isGuaranteedNotToBeUndefOrPoison(V, DemandedElts,
- PoisonOnly, Depth + 1);
+ return isGuaranteedNotToBeUndefOrPoison(V, DemandedElts, Kind,
+ Depth + 1);
});
}
- // TODO: Search for noundef attributes from library functions.
-
- // TODO: Pointers dereferenced by ISD::LOAD/STORE ops are noundef.
-
default:
// Allow the target to implement this method for its nodes.
if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID)
return TLI->isGuaranteedNotToBeUndefOrPoisonForTargetNode(
- Op, DemandedElts, *this, PoisonOnly, Depth);
+ Op, DemandedElts, *this, Kind, Depth);
break;
}
- // If Op can't create undef/poison and none of its operands are undef/poison
- // then Op is never undef/poison.
- // NOTE: TargetNodes can handle this in themselves in
- // isGuaranteedNotToBeUndefOrPoisonForTargetNode or let
- // TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode handle it.
- return !canCreateUndefOrPoison(Op, PoisonOnly, /*ConsiderFlags*/ true,
- Depth) &&
+ return !canCreateUndefOrPoison(Op, Kind, /*ConsiderFlags*/ true, Depth) &&
all_of(Op->ops(), [&](SDValue V) {
- return isGuaranteedNotToBeUndefOrPoison(V, PoisonOnly, Depth + 1);
+ return isGuaranteedNotToBeUndefOrPoison(V, Kind, Depth + 1);
});
}
-bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, bool PoisonOnly,
+bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, UndefPoisonKind Kind,
bool ConsiderFlags,
unsigned Depth) const {
EVT VT = Op.getValueType();
APInt DemandedElts = VT.isFixedLengthVector()
? APInt::getAllOnes(VT.getVectorNumElements())
: APInt(1, 1);
- return canCreateUndefOrPoison(Op, DemandedElts, PoisonOnly, ConsiderFlags,
- Depth);
+ return canCreateUndefOrPoison(Op, DemandedElts, Kind, ConsiderFlags, Depth);
}
bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
- bool PoisonOnly, bool ConsiderFlags,
+ UndefPoisonKind Kind,
+ bool ConsiderFlags,
unsigned Depth) const {
- if (ConsiderFlags && Op->hasPoisonGeneratingFlags())
+ bool IncludeUndef =
+ ((unsigned)Kind & (unsigned)UndefPoisonKind::UndefOnly) != 0;
+ bool IncludePoison =
+ ((unsigned)Kind & (unsigned)UndefPoisonKind::PoisonOnly) != 0;
+
+ // If the instruction has poison-generating flags, it can create poison.
+ // We only return true here if the caller actually cares about poison.
+ if (ConsiderFlags && IncludePoison && Op->hasPoisonGeneratingFlags())
return true;
unsigned Opcode = Op.getOpcode();
@@ -5767,7 +5762,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::AssertAlign:
case ISD::AssertNoFPClass:
// Assertion nodes can create poison if the assertion fails.
- return true;
+ return IncludePoison;
case ISD::FREEZE:
case ISD::CONCAT_VECTORS:
@@ -5814,13 +5809,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::BUILD_PAIR:
case ISD::SPLAT_VECTOR:
case ISD::FABS:
- return false;
-
case ISD::ABS:
- // ISD::ABS defines abs(INT_MIN) -> INT_MIN and never generates poison.
- // Different to Intrinsic::abs.
- return false;
-
case ISD::ADDC:
case ISD::SUBC:
case ISD::ADDE:
@@ -5835,22 +5824,18 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::UMULO:
case ISD::UADDO_CARRY:
case ISD::USUBO_CARRY:
- // No poison on result or overflow flags.
+ case ISD::VECTOR_COMPRESS:
return false;
case ISD::SELECT_CC:
case ISD::SETCC: {
- // Integer setcc cannot create undef or poison.
if (Op.getOperand(0).getValueType().isInteger())
return false;
- // FP compares are more complicated. They can create poison for nan/infinity
- // based on options and flags. The options and flags also cause special
- // nonan condition codes to be used. Those condition codes may be preserved
- // even if the nonan flag is dropped somewhere.
+ // FP compares can create poison based on flags/nonan conditions.
unsigned CCOp = Opcode == ISD::SETCC ? 2 : 4;
ISD::CondCode CCCode = cast<CondCodeSDNode>(Op.getOperand(CCOp))->get();
- return (unsigned)CCCode & 0x10U;
+ return IncludePoison && ((unsigned)CCCode & 0x10U);
}
case ISD::OR:
@@ -5876,37 +5861,39 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::TRUNCATE_SSAT_S:
case ISD::TRUNCATE_SSAT_U:
case ISD::TRUNCATE_USAT_U:
- // No poison except from flags (which is handled above)
return false;
case ISD::SHL:
case ISD::SRL:
case ISD::SRA:
- // If the max shift amount isn't in range, then the shift can
- // create poison.
- return !getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1);
+ // Shift overflows create poison.
+ return IncludePoison &&
+ !getValidMaximumShiftAmount(Op, DemandedElts, Depth + 1);
case ISD::CTTZ_ZERO_UNDEF:
case ISD::CTLZ_ZERO_UNDEF:
- // If the amount is zero then the result will be poison.
- // TODO: Add isKnownNeverZero DemandedElts handling.
- return !isKnownNeverZero(Op.getOperand(0), Depth + 1);
+ // Zero input creates poison for these opcodes.
+ return IncludePoison && !isKnownNeverZero(Op.getOperand(0), Depth + 1);
case ISD::SCALAR_TO_VECTOR:
- // Check if we demand any upper (undef) elements.
- return !PoisonOnly && DemandedElts.ugt(1);
+ // Upper elements of SCALAR_TO_VECTOR are Undef.
+ return IncludeUndef && DemandedElts.ugt(1);
case ISD::INSERT_VECTOR_ELT:
case ISD::EXTRACT_VECTOR_ELT: {
- // Ensure that the element index is in bounds.
+ // Out of bounds indices create poison.
EVT VecVT = Op.getOperand(0).getValueType();
SDValue Idx = Op.getOperand(Opcode == ISD::INSERT_VECTOR_ELT ? 2 : 1);
KnownBits KnownIdx = computeKnownBits(Idx, Depth + 1);
- return KnownIdx.getMaxValue().uge(VecVT.getVectorMinNumElements());
+ return IncludePoison &&
+ KnownIdx.getMaxValue().uge(VecVT.getVectorMinNumElements());
}
case ISD::VECTOR_SHUFFLE: {
- // Check for any demanded shuffle element that is undef.
+ // If a demanded element points to a -1 (Undef) mask index, it creates
+ // Undef.
+ if (!IncludeUndef)
+ return false;
auto *SVN = cast<ShuffleVectorSDNode>(Op);
for (auto [Idx, Elt] : enumerate(SVN->getMask()))
if (Elt < 0 && DemandedElts[Idx])
@@ -5914,19 +5901,14 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
return false;
}
- case ISD::VECTOR_COMPRESS:
- return false;
-
default:
- // Allow the target to implement this method for its nodes.
if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
Opcode == ISD::INTRINSIC_W_CHAIN || Opcode == ISD::INTRINSIC_VOID)
return TLI->canCreateUndefOrPoisonForTargetNode(
- Op, DemandedElts, *this, PoisonOnly, ConsiderFlags, Depth);
+ Op, DemandedElts, *this, Kind, ConsiderFlags, Depth);
break;
}
- // Be conservative and return true.
return true;
}
@@ -6735,7 +6717,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
break;
case ISD::FREEZE:
assert(VT == N1.getValueType() && "Unexpected VT!");
- if (isGuaranteedNotToBeUndefOrPoison(N1, /*PoisonOnly=*/false))
+ if (isGuaranteedNotToBeUndefOrPoison(N1, UndefPoisonKind::UndefOrPoison))
return N1;
break;
case ISD::TokenFactor:
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index cc719b1e67f53..5fb36598d1ed9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -3382,9 +3382,8 @@ bool TargetLowering::SimplifyDemandedVectorElts(
}
case ISD::FREEZE: {
SDValue N0 = Op.getOperand(0);
- if (TLO.DAG.isGuaranteedNotToBeUndefOrPoison(N0, DemandedElts,
- /*PoisonOnly=*/false,
- Depth + 1))
+ if (TLO.DAG.isGuaranteedNotToBeUndefOrPoison(
+ N0, DemandedElts, UndefPoisonKind::UndefOrPoison, Depth + 1))
return TLO.CombineTo(Op, N0);
// TODO: Replace this with the general fold from DAGCombiner::visitFREEZE
@@ -4041,7 +4040,7 @@ const Constant *TargetLowering::getTargetConstantFromLoad(LoadSDNode*) const {
bool TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, unsigned Depth) const {
+ UndefPoisonKind Kind, unsigned Depth) const {
assert(
(Op.getOpcode() >= ISD::BUILTIN_OP_END ||
Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
@@ -4052,17 +4051,16 @@ bool TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
// If Op can't create undef/poison and none of its operands are undef/poison
// then Op is never undef/poison.
- return !canCreateUndefOrPoisonForTargetNode(Op, DemandedElts, DAG, PoisonOnly,
+ return !canCreateUndefOrPoisonForTargetNode(Op, DemandedElts, DAG, Kind,
/*ConsiderFlags*/ true, Depth) &&
all_of(Op->ops(), [&](SDValue V) {
- return DAG.isGuaranteedNotToBeUndefOrPoison(V, PoisonOnly,
- Depth + 1);
+ return DAG.isGuaranteedNotToBeUndefOrPoison(V, Kind, Depth + 1);
});
}
bool TargetLowering::canCreateUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
assert((Op.getOpcode() >= ISD::BUILTIN_OP_END ||
Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ebe9a6b1dfe61..1bb64e4dd48c9 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -33113,7 +33113,7 @@ bool AArch64TargetLowering::SimplifyDemandedBitsForTargetNode(
bool AArch64TargetLowering::canCreateUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
// TODO: Add more target nodes.
switch (Op.getOpcode()) {
@@ -33129,7 +33129,7 @@ bool AArch64TargetLowering::canCreateUndefOrPoisonForTargetNode(
return false;
}
return TargetLowering::canCreateUndefOrPoisonForTargetNode(
- Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
+ Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
}
bool AArch64TargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index d8b4d98b921fa..05630b32dad61 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -913,11 +913,9 @@ class AArch64TargetLowering : public TargetLowering {
TargetLoweringOpt &TLO,
unsigned Depth) const override;
- bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
- const APInt &DemandedElts,
- const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags,
- unsigned Depth) const override;
+ bool canCreateUndefOrPoisonForTargetNode(
+ SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override;
bool isTargetCanonicalConstantNode(SDValue Op) const override;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 752ac6df358be..00150d27d44bc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -6214,7 +6214,7 @@ unsigned AMDGPUTargetLowering::computeNumSignBitsForTargetInstr(
bool AMDGPUTargetLowering::canCreateUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
unsigned Opcode = Op.getOpcode();
switch (Opcode) {
case AMDGPUISD::BFE_I32:
@@ -6222,7 +6222,7 @@ bool AMDGPUTargetLowering::canCreateUndefOrPoisonForTargetNode(
return false;
}
return TargetLowering::canCreateUndefOrPoisonForTargetNode(
- Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
+ Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
}
bool AMDGPUTargetLowering::isKnownNeverNaNForTargetNode(
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
index 6401e4bdb7ea2..f763cf23ec818 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -329,11 +329,9 @@ class AMDGPUTargetLowering : public TargetLowering {
const MachineRegisterInfo &MRI,
unsigned Depth = 0) const override;
- bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
- const APInt &DemandedElts,
- const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags,
- unsigned Depth) const override;
+ bool canCreateUndefOrPoisonForTargetNode(
+ SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override;
bool isKnownNeverNaNForTargetNode(SDValue Op, const APInt &DemandedElts,
const SelectionDAG &DAG, bool SNaN = false,
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index eb757df6a9f28..b4f657376f25d 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -21351,7 +21351,7 @@ bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
bool ARMTargetLowering::canCreateUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
unsigned Opcode = Op.getOpcode();
switch (Opcode) {
case ARMISD::VORRIMM:
@@ -21359,7 +21359,7 @@ bool ARMTargetLowering::canCreateUndefOrPoisonForTargetNode(
return false;
}
return TargetLowering::canCreateUndefOrPoisonForTargetNode(
- Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
+ Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
}
bool ARMTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index e58d872c548e4..87fd141959c7f 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -400,9 +400,12 @@ class VectorType;
bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
unsigned &Cost) const override;
- bool canCreateUndefOrPoisonForTargetNode(
- SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const override;
+ bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
+ const APInt &DemandedElts,
+ const SelectionDAG &DAG,
+ UndefPoisonKind Kind,
+ bool ConsiderFlags,
+ unsigned Depth) const override;
bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
const MachineFunction &MF) const override {
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 83f1b8788a145..4ccc6d32ce9a4 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -23263,7 +23263,7 @@ bool RISCVTargetLowering::SimplifyDemandedBitsForTargetNode(
bool RISCVTargetLowering::canCreateUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
// TODO: Add more target nodes.
switch (Op.getOpcode()) {
@@ -23282,7 +23282,7 @@ bool RISCVTargetLowering::canCreateUndefOrPoisonForTargetNode(
return false;
}
return TargetLowering::canCreateUndefOrPoisonForTargetNode(
- Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
+ Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
}
const Constant *
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 8d88aeb7ae3fc..418cb8cb851d7 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -157,11 +157,9 @@ class RISCVTargetLowering : public TargetLowering {
TargetLoweringOpt &TLO,
unsigned Depth) const override;
- bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
- const APInt &DemandedElts,
- const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags,
- unsigned Depth) const override;
+ bool canCreateUndefOrPoisonForTargetNode(
+ SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const override;
const Constant *getTargetConstantFromLoad(LoadSDNode *LD) const override;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index eacaaddc5e4d4..b14462ecabc95 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -9684,10 +9684,9 @@ SystemZTargetLowering::ComputeNumSignBitsForTargetNode(
return 1;
}
-bool SystemZTargetLowering::
-isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op,
- const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, unsigned Depth) const {
+bool SystemZTargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
+ SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+ UndefPoisonKind Kind, unsigned Depth) const {
switch (Op->getOpcode()) {
case SystemZISD::PCREL_WRAPPER:
case SystemZISD::PCREL_OFFSET:
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index bb3eeba6446d2..65197bbf0ee1d 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -294,7 +294,7 @@ class SystemZTargetLowering : public TargetLowering {
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, unsigned Depth) const override;
+ UndefPoisonKind Kind, unsigned Depth) const override;
ISD::NodeType getExtendForAtomicOps() const override {
return ISD::ANY_EXTEND;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8c570aff23f53..c381ec37c39d5 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -45932,7 +45932,7 @@ SDValue X86TargetLowering::SimplifyMultipleUseDemandedBitsForTargetNode(
bool X86TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, unsigned Depth) const {
+ UndefPoisonKind Kind, unsigned Depth) const {
unsigned NumElts = DemandedElts.getBitWidth();
switch (Op.getOpcode()) {
@@ -45947,10 +45947,10 @@ bool X86TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
DemandedRHS);
return (!DemandedLHS ||
DAG.isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), DemandedLHS,
- PoisonOnly, Depth + 1)) &&
+ Kind, Depth + 1)) &&
(!DemandedRHS ||
DAG.isGuaranteedNotToBeUndefOrPoison(Op.getOperand(1), DemandedRHS,
- PoisonOnly, Depth + 1));
+ Kind, Depth + 1));
}
case X86ISD::INSERTPS:
case X86ISD::BLENDI:
@@ -45984,7 +45984,7 @@ bool X86TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
for (auto Op : enumerate(Ops))
if (!DemandedSrcElts[Op.index()].isZero() &&
!DAG.isGuaranteedNotToBeUndefOrPoison(
- Op.value(), DemandedSrcElts[Op.index()], PoisonOnly, Depth + 1))
+ Op.value(), DemandedSrcElts[Op.index()], Kind, Depth + 1))
return false;
return true;
}
@@ -45995,19 +45995,19 @@ bool X86TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
MVT SrcVT = Src.getSimpleValueType();
if (SrcVT.isVector()) {
APInt DemandedSrc = APInt::getOneBitSet(SrcVT.getVectorNumElements(), 0);
- return DAG.isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrc, PoisonOnly,
+ return DAG.isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrc, Kind,
Depth + 1);
}
- return DAG.isGuaranteedNotToBeUndefOrPoison(Src, PoisonOnly, Depth + 1);
+ return DAG.isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
}
}
return TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode(
- Op, DemandedElts, DAG, PoisonOnly, Depth);
+ Op, DemandedElts, DAG, Kind, Depth);
}
bool X86TargetLowering::canCreateUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+ UndefPoisonKind Kind, bool ConsiderFlags, unsigned Depth) const {
switch (Op.getOpcode()) {
// SSE bit logic.
@@ -46103,7 +46103,7 @@ bool X86TargetLowering::canCreateUndefOrPoisonForTargetNode(
}
}
return TargetLowering::canCreateUndefOrPoisonForTargetNode(
- Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
+ Op, DemandedElts, DAG, Kind, ConsiderFlags, Depth);
}
bool X86TargetLowering::isSplatValueForTargetNode(SDValue Op,
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index fc16053caa705..f3b4f69e739c1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1367,11 +1367,14 @@ namespace llvm {
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, unsigned Depth) const override;
+ UndefPoisonKind Kind, unsigned Depth) const override;
- bool canCreateUndefOrPoisonForTargetNode(
- SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
- bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const override;
+ bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
+ const APInt &DemandedElts,
+ const SelectionDAG &DAG,
+ UndefPoisonKind Kind,
+ bool ConsiderFlags,
+ unsigned Depth) const override;
bool isSplatValueForTargetNode(SDValue Op, const APInt &DemandedElts,
APInt &UndefElts, const SelectionDAG &DAG,
diff --git a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index caec229207ea6..1d469e475db7d 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -731,10 +731,10 @@ def LowerUnPackOp : Op<Transform_Dialect, "structured.lower_unpack", [
let arguments = (ins Transform_ConcreteOpType<"linalg.unpack">:$target,
DefaultValuedAttr<BoolAttr, "true">:$lowerUnpadLikeWithExtractSlice);
let results = (outs Transform_ConcreteOpType<"tensor.empty">:$empty_op,
- Transform_ConcreteOpType<"linalg.transpose">:$transpose_op,
- Transform_ConcreteOpType<"tensor.collapse_shape">:$collapse_shape_op,
- Transform_ConcreteOpType<"tensor.extract_slice">:$extract_slice_op,
- Transform_ConcreteOpType<"linalg.copy">:$copy_op);
+ Transform_ConcreteOpType<"linalg.transpose">:$transpose_op,
+ Transform_ConcreteOpType<"tensor.collapse_shape">:$collapse_shape_op,
+ Transform_ConcreteOpType<"tensor.extract_slice">:$extract_slice_op,
+ Transform_ConcreteOpType<"linalg.copy">:$copy_op);
let assemblyFormat = [{
$target attr-dict `:` functional-type(operands, results)
}];
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index f179cfd752c62..4b5d65ef6cf6c 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -29,9 +29,9 @@ include "mlir/Interfaces/InferTypeOpInterface.td"
def OpenACC_ReductionInitOp
: OpenACC_Op<"reduction_init",
[SameOperandsAndResultType, RecursiveMemoryEffects,
- DeclareOpInterfaceMethods<RegionBranchOpInterface,
- ["getRegionInvocationBounds",
- "getSuccessorInputs"]>,
+ DeclareOpInterfaceMethods<
+ RegionBranchOpInterface, ["getRegionInvocationBounds",
+ "getSuccessorInputs"]>,
SingleBlockImplicitTerminator<"YieldOp">]> {
let summary = "Allocate and initialize a reduction variable from a recipe";
let description = [{
@@ -44,7 +44,7 @@ def OpenACC_ReductionInitOp
reduction_operator specifies the reduction kind (e.g. add, mul).
}];
let arguments = (ins OpenACC_AnyPointerOrMappableType:$var,
- OpenACC_ReductionOperatorAttr:$reductionOperator);
+ OpenACC_ReductionOperatorAttr:$reductionOperator);
let results = (outs OpenACC_AnyPointerOrMappableType:$result);
let regions = (region AnyRegion:$region);
let assemblyFormat = [{
@@ -60,9 +60,9 @@ def OpenACC_ReductionInitOp
def OpenACC_ReductionCombineRegionOp
: OpenACC_Op<"reduction_combine_region",
[SameTypeOperands, RecursiveMemoryEffects,
- DeclareOpInterfaceMethods<RegionBranchOpInterface,
- ["getRegionInvocationBounds",
- "getSuccessorInputs"]>,
+ DeclareOpInterfaceMethods<
+ RegionBranchOpInterface, ["getRegionInvocationBounds",
+ "getSuccessorInputs"]>,
SingleBlockImplicitTerminator<"YieldOp">]> {
let summary = "Combine a reduction private value with its original (recipe)";
let description = [{
@@ -76,7 +76,7 @@ def OpenACC_ReductionCombineRegionOp
The srcVar operand is typically the result of acc.reduction_init.
}];
let arguments = (ins OpenACC_AnyPointerOrMappableType:$destVar,
- OpenACC_AnyPointerOrMappableType:$srcVar);
+ OpenACC_AnyPointerOrMappableType:$srcVar);
let results = (outs);
let regions = (region AnyRegion:$region);
let assemblyFormat = [{
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index 2bb1654cb6369..247038623375f 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -2842,10 +2842,13 @@ def OpenACC_LoopOp
}
// Yield operation for the acc.loop and acc.parallel operations.
-def OpenACC_YieldOp : OpenACC_Op<"yield", [Pure, ReturnLike, Terminator,
- ParentOneOf<["FirstprivateRecipeOp, LoopOp, ParallelOp, PrivateRecipeOp,"
- "ReductionRecipeOp, ReductionInitOp, ReductionCombineRegionOp,"
- "SerialOp, AtomicUpdateOp"]>]> {
+def OpenACC_YieldOp
+ : OpenACC_Op<"yield", [Pure, ReturnLike, Terminator,
+ ParentOneOf<["FirstprivateRecipeOp, LoopOp, "
+ "ParallelOp, PrivateRecipeOp,"
+ "ReductionRecipeOp, ReductionInitOp, "
+ "ReductionCombineRegionOp,"
+ "SerialOp, AtomicUpdateOp"]>]> {
let summary = "Acc yield and termination operation";
let description = [{
diff --git a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
index 8e00846255254..be997a51d2941 100644
--- a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
@@ -372,8 +372,10 @@ def OffloadLiveInValueCanonicalization : Pass<"offload-livein-value-canonicaliza
let dependentDialects = ["mlir::acc::OpenACCDialect"];
}
-def ACCRecipeMaterialization : Pass<"acc-recipe-materialization", "mlir::ModuleOp"> {
- let summary = "Materialize OpenACC private, firstprivate and reduction recipes";
+def ACCRecipeMaterialization
+ : Pass<"acc-recipe-materialization", "mlir::ModuleOp"> {
+ let summary =
+ "Materialize OpenACC private, firstprivate and reduction recipes";
let description = [{
Materializes OpenACC privatization, firstprivate and reduction recipes by
cloning init, copy, combiner, and destroy into the construct. Replaces recipe
@@ -381,7 +383,8 @@ def ACCRecipeMaterialization : Pass<"acc-recipe-materialization", "mlir::ModuleO
acc.reduction_combine_region for reductions) and removes unused recipe
symbols.
}];
- let dependentDialects = ["mlir::acc::OpenACCDialect", "mlir::arith::ArithDialect"];
+ let dependentDialects = ["mlir::acc::OpenACCDialect",
+ "mlir::arith::ArithDialect"];
}
def OffloadTargetVerifier : Pass<"offload-target-verifier", "mlir::func::FuncOp"> {
More information about the cfe-commits
mailing list