summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-03-02 18:36:08 +0000
committerSanjay Patel <spatel@rotateright.com>2018-03-02 18:36:08 +0000
commit46b083ef4a3424b1e0e6b488d390ce759759f8e9 (patch)
tree52e928e9d56f6af78273d4466ada7bbae57485ec
parentf608812bdef3f4c09857beb2ca20269387fe61c7 (diff)
downloadbcm5719-llvm-46b083ef4a3424b1e0e6b488d390ce759759f8e9.tar.gz
bcm5719-llvm-46b083ef4a3424b1e0e6b488d390ce759759f8e9.zip
[PatternMatch, InstSimplify] fix m_NaN to work with vector constants and use it
This is NFC for the moment (and independent of any potential NaN semantic controversy). Besides making the code in InstSimplify easier to read, the motivation is to eventually allow undef elements in vector constants to match too. A proposal to add the base logic for that is in D43792. llvm-svn: 326600
-rw-r--r--llvm/include/llvm/IR/Constant.h4
-rw-r--r--llvm/include/llvm/IR/PatternMatch.h2
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp15
-rw-r--r--llvm/lib/IR/Constants.cpp13
4 files changed, 24 insertions, 10 deletions
diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h
index 16edfc4382d..6048160d8e6 100644
--- a/llvm/include/llvm/IR/Constant.h
+++ b/llvm/include/llvm/IR/Constant.h
@@ -83,6 +83,10 @@ public:
/// vector has an exact multiplicative inverse for each element in the vector.
bool hasExactInverseFP() const;
+ /// Return true if this is a floating-point NaN constant or a vector
+ /// floating-point constant with all NaN elements.
+ bool isNaN() const;
+
/// Return true if evaluation of this constant could trap. This is true for
/// things like constant expressions that could divide by zero.
bool canTrap() const;
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index e7e3303eaa3..1c071cb5331 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -173,7 +173,7 @@ inline match_any_zero m_AnyZero() { return match_any_zero(); }
struct match_nan {
template <typename ITy> bool match(ITy *V) {
- if (const auto *C = dyn_cast<ConstantFP>(V))
+ if (const auto *C = dyn_cast<Constant>(V))
return C->isNaN();
return false;
}
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index eee6d531643..40ed69a5588 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3355,6 +3355,12 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
return getTrue(RetTy);
}
+ // NaN is unordered; NaN is not ordered.
+ assert((FCmpInst::isOrdered(Pred) || FCmpInst::isUnordered(Pred)) &&
+ "Comparison must be either ordered or unordered");
+ if (match(RHS, m_NaN()))
+ return ConstantInt::get(RetTy, CmpInst::isUnordered(Pred));
+
// fcmp pred x, undef and fcmp pred undef, x
// fold to true if unordered, false if ordered
if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS)) {
@@ -3374,15 +3380,6 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// Handle fcmp with constant RHS.
const APFloat *C;
if (match(RHS, m_APFloat(C))) {
- // If the constant is a nan, see if we can fold the comparison based on it.
- if (C->isNaN()) {
- if (FCmpInst::isOrdered(Pred)) // True "if ordered and foo"
- return getFalse(RetTy);
- assert(FCmpInst::isUnordered(Pred) &&
- "Comparison must be either ordered or unordered!");
- // True if unordered.
- return getTrue(RetTy);
- }
// Check whether the constant is an infinity.
if (C->isInfinity()) {
if (C->isNegative()) {
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 8b375bcff76..ad3dc174fe3 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -241,6 +241,19 @@ bool Constant::hasExactInverseFP() const {
return true;
}
+bool Constant::isNaN() const {
+ if (auto *CFP = dyn_cast<ConstantFP>(this))
+ return CFP->isNaN();
+ if (!getType()->isVectorTy())
+ return false;
+ for (unsigned i = 0, e = getType()->getVectorNumElements(); i != e; ++i) {
+ auto *CFP = dyn_cast_or_null<ConstantFP>(this->getAggregateElement(i));
+ if (!CFP || !CFP->isNaN())
+ return false;
+ }
+ return true;
+}
+
/// Constructor to create a '0' constant of arbitrary type.
Constant *Constant::getNullValue(Type *Ty) {
switch (Ty->getTypeID()) {
OpenPOWER on IntegriCloud