[Mlir-commits] [llvm] [mlir] [DAG] Refactor Undef/Poison queries to use UndefPoisonKind enum. (PR #195508)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun May 3 02:13:38 PDT 2026
https://github.com/levi42x updated https://github.com/llvm/llvm-project/pull/195508
>From 0b49a0accf752e86d1ea7f61f10aa3959b79ba4b 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
---
llvm/test/CodeGen/X86/known-never-zero.ll | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index 910f1375ed1ca..5ca259a8513b2 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -1319,7 +1319,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:
@@ -1328,8 +1330,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
@@ -1452,7 +1455,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:
@@ -1461,8 +1466,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 0a2cdf5f38cc6543ec62372d8aac2886eb01dc97 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 5ca259a8513b2..835c0a585ac0b 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -2807,8 +2807,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
@@ -2841,11 +2842,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:
@@ -2857,8 +2859,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 15740a6bd80cf2150bd1c00fc3576829ed0e29c3 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 | 48 ++++++++++-------------
1 file changed, 21 insertions(+), 27 deletions(-)
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index 835c0a585ac0b..2345e91fe92d9 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -422,15 +422,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
@@ -1319,9 +1322,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:
@@ -1330,9 +1331,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
@@ -1455,9 +1455,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:
@@ -1466,9 +1464,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
@@ -2807,9 +2804,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
@@ -2842,12 +2838,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:
@@ -2859,9 +2854,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 ba7e1049a99034dbc6431b416974b509d86465f3 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
---
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 | 171 ++++++++----------
.../CodeGen/SelectionDAG/TargetLowering.cpp | 14 +-
.../Target/AArch64/AArch64ISelLowering.cpp | 4 +-
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 8 +-
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 7 +-
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 | 13 +-
.../mlir/Dialect/OpenACC/Transforms/Passes.td | 9 +-
24 files changed, 231 insertions(+), 226 deletions(-)
create mode 100644 llvm/include/llvm/Support/UndefPoisonKind.h
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index b68d1fc7ea6ca..8afc9c6512b5d 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -42,6 +42,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownFPClass.h"
#include "llvm/Support/RecyclingAllocator.h"
+#include "llvm/Support/UndefPoisonKind.h"
#include <cassert>
#include <cstdint>
#include <functional>
@@ -1771,9 +1772,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);
@@ -2333,22 +2335,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
@@ -2356,35 +2359,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 9b0bfa111f2d5..88a28da154619 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -55,6 +55,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>
@@ -4471,15 +4472,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 8b82a1d413149..1f2f9fa62269d 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>
@@ -7633,12 +7634,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;
}
@@ -7796,7 +7791,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,
@@ -7904,7 +7900,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.
@@ -8301,7 +8299,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.
@@ -8329,7 +8327,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.
@@ -8393,13 +8391,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 37af0716df9ec..3ec55be7aadbb 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>
@@ -1787,14 +1788,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 75539da583342..a1a5ffa84b5f6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -65,6 +65,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"
@@ -17870,7 +17871,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.
@@ -17901,7 +17902,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();
@@ -17942,7 +17943,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;
@@ -24827,8 +24829,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 f91f0bb63cebc..b90b9b95d8aa6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2570,8 +2570,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);
}
@@ -3669,7 +3669,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
@@ -4935,7 +4936,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:
@@ -5609,19 +5611,23 @@ 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)
return true;
- APInt DemandedElts = getDemandAllEltsMask(Op);
- return isGuaranteedNotToBeUndefOrPoison(Op, DemandedElts, PoisonOnly, Depth);
+ EVT VT = Op.getValueType();
+ APInt DemandedElts = VT.isFixedLengthVector()
+ ? APInt::getAllOnes(VT.getVectorNumElements())
+ : APInt(1, 1);
+ 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();
@@ -5635,6 +5641,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:
@@ -5647,16 +5656,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;
@@ -5668,7 +5676,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);
}
@@ -5684,10 +5692,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;
}
@@ -5700,7 +5708,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;
@@ -5715,14 +5723,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;
}
@@ -5731,17 +5739,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;
@@ -5751,12 +5758,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;
}
@@ -5764,12 +5771,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:
@@ -5795,55 +5800,50 @@ 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 {
- APInt DemandedElts = getDemandAllEltsMask(Op);
- return canCreateUndefOrPoison(Op, DemandedElts, PoisonOnly, ConsiderFlags,
- Depth);
+ EVT VT = Op.getValueType();
+ APInt DemandedElts = VT.isFixedLengthVector()
+ ? APInt::getAllOnes(VT.getVectorNumElements())
+ : APInt(1, 1);
+ 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();
@@ -5853,7 +5853,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:
@@ -5900,13 +5900,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:
@@ -5921,22 +5915,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:
@@ -5962,37 +5952,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])
@@ -6000,19 +5992,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;
}
@@ -6985,7 +6972,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 6aaf1bed7aae8..829bb1ca53b59 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -3374,9 +3374,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
@@ -4033,7 +4032,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 ||
@@ -4044,17 +4043,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 f5082b779d1db..f1ffda6078837 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -33310,7 +33310,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()) {
@@ -33326,7 +33326,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 80d49bb2ed318..2e66b5ad896ef 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -906,11 +906,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 e05213b2aaf93..ee41e5bf73ae2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -6070,7 +6070,8 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
bool SelfMultiply = Op.getOperand(0) == Op.getOperand(1);
if (SelfMultiply)
SelfMultiply &= DAG.isGuaranteedNotToBeUndefOrPoison(
- Op.getOperand(0), DemandedElts, false, Depth + 1);
+ Op.getOperand(0), DemandedElts, UndefPoisonKind::UndefOrPoison,
+ Depth + 1);
Known = KnownBits::mul(LHSKnown, RHSKnown, SelfMultiply);
break;
@@ -6259,7 +6260,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:
@@ -6267,7 +6268,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 8085b64567c59..fc61fe033de0e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -342,11 +342,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 cbff40f697b9b..ff8df9b33b3cc 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -21540,7 +21540,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:
@@ -21548,7 +21548,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 491beb5434555..10f5442d7429b 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -402,9 +402,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 94361f0657fed..c3fe9e65bd211 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -22974,7 +22974,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()) {
@@ -22995,7 +22995,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 1be58c56d56d7..54802cf62a13e 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 bd9a172f9d9d7..e450b27798a57 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -9671,10 +9671,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 29daeb5c23cc8..5dfe1400f1543 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -45982,7 +45982,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()) {
@@ -46001,10 +46001,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:
@@ -46038,7 +46038,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;
}
@@ -46049,19 +46049,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.
@@ -46157,7 +46157,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 515f28122a00a..0d05c5772a707 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -367,11 +367,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 7f155c7f75d75..6a4807cbaf7fc 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -768,10 +768,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 69848101a5e4d..e998c9c0ed714 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 32ecaa6bc2d42..17865bd29703d 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -2902,10 +2902,15 @@ 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, ComputeRegionOp"]>]> {
+def OpenACC_YieldOp
+ : OpenACC_Op<
+ "yield", [Pure, ReturnLike, Terminator,
+ ParentOneOf<["FirstprivateRecipeOp", "LoopOp", "ParallelOp",
+ "PrivateRecipeOp", "ReductionRecipeOp",
+ "ReductionInitOp", "ReductionCombineRegionOp",
+ "SerialOp", "AtomicUpdateOp",
+ "ComputeRegionOp"]>]> {
+
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 786d338cea600..7bb73feaaf3d5 100644
--- a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
@@ -379,8 +379,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
@@ -388,7 +390,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 Mlir-commits
mailing list