[Mlir-commits] [clang] [llvm] [mlir] [DAG] Refactor Undef/Poison queries to use UndefPoisonKind enum. (PR #195508)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sun May 3 01:14:32 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-linalg

Author: Shekhar (levi42x)

<details>
<summary>Changes</summary>

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.

---

Patch is 60.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/195508.diff


26 Files Affected:

- (modified) clang/lib/Serialization/ASTWriter.cpp (+2-1) 
- (modified) llvm/include/llvm/CodeGen/SelectionDAG.h (+34-31) 
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+5-5) 
- (added) llvm/include/llvm/Support/UndefPoisonKind.h (+16) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+11-13) 
- (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+1-8) 
- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+7-5) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+73-91) 
- (modified) llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp (+6-8) 
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+2-2) 
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.h (+3-5) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp (+2-2) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h (+3-5) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+2-2) 
- (modified) llvm/lib/Target/ARM/ARMISelLowering.h (+6-3) 
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+2-2) 
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+3-5) 
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.cpp (+3-4) 
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.h (+1-1) 
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+9-9) 
- (modified) llvm/lib/Target/X86/X86ISelLowering.h (+7-4) 
- (modified) llvm/test/CodeGen/X86/known-never-zero.ll (+9-18) 
- (modified) mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td (+4-4) 
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td (+8-8) 
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td (+7-4) 
- (modified) mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td (+6-3) 


``````````diff
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 2c0e9c8c2f24d..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))
  ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/195508


More information about the Mlir-commits mailing list