diff options
author | Justin Lebar <jlebar@google.com> | 2017-01-26 00:10:26 +0000 |
---|---|---|
committer | Justin Lebar <jlebar@google.com> | 2017-01-26 00:10:26 +0000 |
commit | 7e3184c4122e90772e983e1fe16dccf3b32ad8b6 (patch) | |
tree | 8ea3bcb67b6cf60cb2d89bb4ad4b443b170369d5 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | a31f9dd69a944042059e4ddec2979669f9a70076 (diff) | |
download | bcm5719-llvm-7e3184c4122e90772e983e1fe16dccf3b32ad8b6.tar.gz bcm5719-llvm-7e3184c4122e90772e983e1fe16dccf3b32ad8b6.zip |
[ValueTracking] Implement SignBitMustBeZero correctly for sqrt.
Summary:
Previously we assumed that the result of sqrt(x) always had 0 as its
sign bit. But sqrt(-0) == -0.
Reviewers: hfinkel, efriedma, sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D28928
llvm-svn: 293115
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index dc8de6d58a3..ad4e668efbf 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2645,7 +2645,8 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V, return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, Depth + 1); case Instruction::Call: - Intrinsic::ID IID = getIntrinsicForCallSite(cast<CallInst>(I), TLI); + const auto *CI = cast<CallInst>(I); + Intrinsic::ID IID = getIntrinsicForCallSite(CI, TLI); switch (IID) { default: break; @@ -2662,12 +2663,19 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V, case Intrinsic::exp: case Intrinsic::exp2: case Intrinsic::fabs: - case Intrinsic::sqrt: return true; + + case Intrinsic::sqrt: + // sqrt(x) is always >= -0 or NaN. Moreover, sqrt(x) == -0 iff x == -0. + if (!SignBitOnly) + return true; + return CI->hasNoNaNs() && (CI->hasNoSignedZeros() || + CannotBeNegativeZero(CI->getOperand(0), TLI)); + case Intrinsic::powi: - if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { + if (ConstantInt *Exponent = dyn_cast<ConstantInt>(I->getOperand(1))) { // powi(x,n) is non-negative if n is even. - if (CI->getBitWidth() <= 64 && CI->getSExtValue() % 2u == 0) + if (Exponent->getBitWidth() <= 64 && Exponent->getSExtValue() % 2u == 0) return true; } return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, |