[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