aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2018-08-09 22:40:08 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2018-08-09 22:40:08 +0000
commitd54b7f059290102b0ff007843ecf0668e833c118 (patch)
tree1d9d994433fb077ea32b27c342ff408ad21a2f27 /llvm/lib/Analysis/ValueTracking.cpp
parent41b25c6cf4a9cd65021a1e71bc3168b861545ada (diff)
downloadllvm-d54b7f059290102b0ff007843ecf0668e833c118.zip
llvm-d54b7f059290102b0ff007843ecf0668e833c118.tar.gz
llvm-d54b7f059290102b0ff007843ecf0668e833c118.tar.bz2
ValueTracking: Start enhancing isKnownNeverNaN
llvm-svn: 339399
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 2aac19a..2484cec 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2841,10 +2841,10 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
default:
break;
case Intrinsic::maxnum:
- return (isKnownNeverNaN(I->getOperand(0)) &&
+ return (isKnownNeverNaN(I->getOperand(0), TLI) &&
cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI,
SignBitOnly, Depth + 1)) ||
- (isKnownNeverNaN(I->getOperand(1)) &&
+ (isKnownNeverNaN(I->getOperand(1), TLI) &&
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI,
SignBitOnly, Depth + 1));
@@ -2909,7 +2909,8 @@ bool llvm::SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI) {
return cannotBeOrderedLessThanZeroImpl(V, TLI, true, 0);
}
-bool llvm::isKnownNeverNaN(const Value *V) {
+bool llvm::isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI,
+ unsigned Depth) {
assert(V->getType()->isFPOrFPVectorTy() && "Querying for NaN on non-FP type");
// If we're told that NaNs won't happen, assume they won't.
@@ -2924,6 +2925,23 @@ bool llvm::isKnownNeverNaN(const Value *V) {
if (auto *CFP = dyn_cast<ConstantFP>(V))
return !CFP->isNaN();
+ if (Depth == MaxDepth)
+ return false;
+
+ if (const auto *II = dyn_cast<IntrinsicInst>(V)) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::canonicalize:
+ case Intrinsic::fabs:
+ case Intrinsic::copysign:
+ return isKnownNeverNaN(II->getArgOperand(0), TLI, Depth + 1);
+ case Intrinsic::sqrt:
+ return isKnownNeverNaN(II->getArgOperand(0), TLI, Depth + 1) &&
+ CannotBeOrderedLessThanZero(II->getArgOperand(0), TLI);
+ default:
+ return false;
+ }
+ }
+
// Bail out for constant expressions, but try to handle vector constants.
if (!V->getType()->isVectorTy() || !isa<Constant>(V))
return false;