diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2018-08-09 22:40:08 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2018-08-09 22:40:08 +0000 |
commit | d54b7f059290102b0ff007843ecf0668e833c118 (patch) | |
tree | 1d9d994433fb077ea32b27c342ff408ad21a2f27 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 41b25c6cf4a9cd65021a1e71bc3168b861545ada (diff) | |
download | llvm-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.cpp | 24 |
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; |