[llvm] [DAG] Early exit for flags in canCreateUndefOrPoison [nfc] (PR #89834)

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 24 07:38:52 PDT 2024


https://github.com/preames updated https://github.com/llvm/llvm-project/pull/89834

>From b500a487f18015498402a825402a46e87880d6d4 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Tue, 23 Apr 2024 14:19:38 -0700
Subject: [PATCH 1/3] [DAG] Early exit for flags in canCreateUndefOrPoison
 [nfc]

This matches the style used in the Analysis version of this routine,
and makes it less likely we'll miss a poison generating flag in
future changes.  Unlike IR, the check for poison generating flags is
near trivial since all nodes have the SDFlags storage, and all bits
in that storage is poison generating.
---
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h |  7 +++++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 28 ++++++-------------
 2 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 261f7e49e5c8ca..bf73015ed888ed 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -452,6 +452,13 @@ struct SDNodeFlags {
   bool hasNoFPExcept() const { return NoFPExcept; }
   bool hasUnpredictable() const { return Unpredictable; }
 
+  bool hasAny() const {
+    return NoUnsignedWrap || NoSignedWrap || Exact || Disjoint || NonNeg ||
+           NoNaNs || NoInfs || NoSignedZeros || AllowReciprocal ||
+           AllowContract || ApproximateFuncs || AllowReassociation ||
+           NoFPExcept || Unpredictable;
+  }
+
   /// Clear any flags in this flag set that aren't also set in Flags. All
   /// flags will be cleared if Flags are undefined.
   void intersectWith(const SDNodeFlags Flags) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b63b8b893fdbf1..de0c5c0305ad57 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5095,6 +5095,10 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   if (VT.isScalableVector())
     return true;
 
+  // Matches hasPoisonGeneratingFlags().
+  if (ConsiderFlags && Op->getFlags().hasAny())
+    return true;
+
   unsigned Opcode = Op.getOpcode();
   switch (Opcode) {
   case ISD::FREEZE:
@@ -5134,34 +5138,20 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
       return true;
 
     const TargetOptions &Options = getTarget().Options;
-    return Options.NoNaNsFPMath || Options.NoInfsFPMath ||
-           (ConsiderFlags &&
-            (Op->getFlags().hasNoNaNs() || Op->getFlags().hasNoInfs()));
+    return Options.NoNaNsFPMath || Options.NoInfsFPMath;
   }
 
-  // Matches hasPoisonGeneratingFlags().
+  case ISD::OR:
   case ISD::ZERO_EXTEND:
-    return ConsiderFlags && Op->getFlags().hasNonNeg();
-
   case ISD::ADD:
   case ISD::SUB:
   case ISD::MUL:
-    // Matches hasPoisonGeneratingFlags().
-    return ConsiderFlags && (Op->getFlags().hasNoSignedWrap() ||
-                             Op->getFlags().hasNoUnsignedWrap());
+    // No poison except from flags (which is handled above)
+    return false;
 
   case ISD::SHL:
     // If the max shift amount isn't in range, then the shift can create poison.
-    if (!getValidMaximumShiftAmountConstant(Op, DemandedElts))
-      return true;
-
-    // Matches hasPoisonGeneratingFlags().
-    return ConsiderFlags && (Op->getFlags().hasNoSignedWrap() ||
-                             Op->getFlags().hasNoUnsignedWrap());
-
-  // Matches hasPoisonGeneratingFlags().
-  case ISD::OR:
-    return ConsiderFlags && Op->getFlags().hasDisjoint();
+    return !getValidMaximumShiftAmountConstant(Op, DemandedElts);
 
   case ISD::SCALAR_TO_VECTOR:
     // Check if we demand any upper (undef) elements.

>From 1ac2049d00a112c5666c7a1fbf47921ba81aa0a6 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Tue, 23 Apr 2024 18:22:40 -0700
Subject: [PATCH 2/3] Only some fastmath flags imply poison

---
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h  | 10 ++++++----
 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  3 +--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index bf73015ed888ed..e0ca37682d8aa2 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -452,11 +452,9 @@ struct SDNodeFlags {
   bool hasNoFPExcept() const { return NoFPExcept; }
   bool hasUnpredictable() const { return Unpredictable; }
 
-  bool hasAny() const {
+  bool hasPoisonGeneratingFlags() const {
     return NoUnsignedWrap || NoSignedWrap || Exact || Disjoint || NonNeg ||
-           NoNaNs || NoInfs || NoSignedZeros || AllowReciprocal ||
-           AllowContract || ApproximateFuncs || AllowReassociation ||
-           NoFPExcept || Unpredictable;
+           NoNaNs || NoInfs || NoFPExcept || Unpredictable;
   }
 
   /// Clear any flags in this flag set that aren't also set in Flags. All
@@ -1006,6 +1004,10 @@ END_TWO_BYTE_PACK()
   /// If Flags is not in a defined state then this has no effect.
   void intersectFlagsWith(const SDNodeFlags Flags);
 
+  bool hasPoisonGeneratingFlags() const {
+    return getFlags().hasPoisonGeneratingFlags();
+  }
+
   void setCFIType(uint32_t Type) { CFIType = Type; }
   uint32_t getCFIType() const { return CFIType; }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index de0c5c0305ad57..e322cf6947f449 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5095,8 +5095,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   if (VT.isScalableVector())
     return true;
 
-  // Matches hasPoisonGeneratingFlags().
-  if (ConsiderFlags && Op->getFlags().hasAny())
+  if (ConsiderFlags && Op->hasPoisonGeneratingFlags())
     return true;
 
   unsigned Opcode = Op.getOpcode();

>From 60bd0e1982129b1fb49b2a1199ed034e04298955 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Wed, 24 Apr 2024 07:28:57 -0700
Subject: [PATCH 3/3] Remove NoFPExcept and Unpredictable

---
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index e0ca37682d8aa2..b674d005976408 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -452,11 +452,6 @@ struct SDNodeFlags {
   bool hasNoFPExcept() const { return NoFPExcept; }
   bool hasUnpredictable() const { return Unpredictable; }
 
-  bool hasPoisonGeneratingFlags() const {
-    return NoUnsignedWrap || NoSignedWrap || Exact || Disjoint || NonNeg ||
-           NoNaNs || NoInfs || NoFPExcept || Unpredictable;
-  }
-
   /// Clear any flags in this flag set that aren't also set in Flags. All
   /// flags will be cleared if Flags are undefined.
   void intersectWith(const SDNodeFlags Flags) {
@@ -1005,7 +1000,10 @@ END_TWO_BYTE_PACK()
   void intersectFlagsWith(const SDNodeFlags Flags);
 
   bool hasPoisonGeneratingFlags() const {
-    return getFlags().hasPoisonGeneratingFlags();
+    SDNodeFlags Flags = getFlags();
+    return Flags.hasNoUnsignedWrap() || Flags.hasNoSignedWrap() ||
+           Flags.hasExact() || Flags.hasDisjoint() || Flags.hasNonNeg() ||
+           Flags.hasNoNaNs() || Flags.hasNoInfs();
   }
 
   void setCFIType(uint32_t Type) { CFIType = Type; }



More information about the llvm-commits mailing list