[llvm] 425cbbc - [Operator] Add hasPoisonGeneratingFlags [mostly NFC]

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 27 11:28:36 PDT 2021


Author: Philip Reames
Date: 2021-10-27T11:25:40-07:00
New Revision: 425cbbc602c970e20785e005a7c9d5716a5fac68

URL: https://github.com/llvm/llvm-project/commit/425cbbc602c970e20785e005a7c9d5716a5fac68
DIFF: https://github.com/llvm/llvm-project/commit/425cbbc602c970e20785e005a7c9d5716a5fac68.diff

LOG: [Operator] Add hasPoisonGeneratingFlags [mostly NFC]

This method parallels the dropPoisonGeneratingFlags on Instruction, but is hoisted to operator to handle constant expressions as well.

This is mostly code movement, but I did go ahead and add the inrange constexpr gep case.  This had been discussed previously, but apparently never followed up o.

Added: 
    

Modified: 
    llvm/include/llvm/IR/Operator.h
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/lib/IR/Instruction.cpp
    llvm/lib/IR/Operator.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h
index d3a89f94a9ec..b83d83f0d0ab 100644
--- a/llvm/include/llvm/IR/Operator.h
+++ b/llvm/include/llvm/IR/Operator.h
@@ -59,6 +59,10 @@ class Operator : public User {
   static bool classof(const Value *V) {
     return isa<Instruction>(V) || isa<ConstantExpr>(V);
   }
+
+  /// Return true if this operator has flags which may cause this operator
+  /// to evaluate to poison despite having non-poison inputs.
+  bool hasPoisonGeneratingFlags() const;
 };
 
 /// Utility class for integer operators which may exhibit overflow - Add, Sub,

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c641652ef53c..9a87227a24b4 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4963,19 +4963,9 @@ bool llvm::isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
 
 static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
                                    bool ConsiderFlags) {
-  if (ConsiderFlags) {
-    // See whether I has flags that may create poison
-    if (const auto *OvOp = dyn_cast<OverflowingBinaryOperator>(Op)) {
-      if (OvOp->hasNoSignedWrap() || OvOp->hasNoUnsignedWrap())
-        return true;
-    }
-    if (const auto *ExactOp = dyn_cast<PossiblyExactOperator>(Op))
-      if (ExactOp->isExact())
-        return true;
-    if (const auto *GEP = dyn_cast<GEPOperator>(Op))
-      if (GEP->isInBounds())
-        return true;
-  }
+
+  if (ConsiderFlags && Op->hasPoisonGeneratingFlags())
+    return true;
 
   // TODO: this should really be under the ConsiderFlags block, but currently
   // these are not dropped by dropPoisonGeneratingFlags

diff  --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 25d0440215b3..2463773aefd1 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -163,6 +163,9 @@ void Instruction::dropPoisonGeneratingFlags() {
     break;
   }
   // TODO: FastMathFlags!
+
+  assert(!cast<Operator>(this)->hasPoisonGeneratingFlags() &&
+         "must be kept in sync");
 }
 
 void Instruction::dropUndefImplyingAttrsAndUnknownMetadata(

diff  --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index f9dbed31c44c..cf309ffd6212 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -19,6 +19,31 @@
 #include "ConstantsContext.h"
 
 namespace llvm {
+bool Operator::hasPoisonGeneratingFlags() const {
+  switch (getOpcode()) {
+  case Instruction::Add:
+  case Instruction::Sub:
+  case Instruction::Mul:
+  case Instruction::Shl: {
+    auto *OBO = cast<OverflowingBinaryOperator>(this);
+    return OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap();
+  }
+  case Instruction::UDiv:
+  case Instruction::SDiv:
+  case Instruction::AShr:
+  case Instruction::LShr:
+    return cast<PossiblyExactOperator>(this)->isExact();
+  case Instruction::GetElementPtr: {
+    auto *GEP = cast<GEPOperator>(this);
+    // Note: inrange exists on constexpr only
+    return GEP->isInBounds() || GEP->getInRangeIndex() != None;
+  }
+  default:
+    return false;
+  }
+  // TODO: FastMathFlags!  (On instructions, but not constexpr)
+}
+
 Type *GEPOperator::getSourceElementType() const {
   if (auto *I = dyn_cast<GetElementPtrInst>(this))
     return I->getSourceElementType();


        


More information about the llvm-commits mailing list