summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2017-01-27 00:58:34 +0000
committerJustin Lebar <jlebar@google.com>2017-01-27 00:58:34 +0000
commit322c127bee3f9efc0e9f78d3ff3957b60c653d20 (patch)
tree30247071bec6c05f66710543e3b83d0a9c7651a7 /llvm/lib/Analysis
parentcb9b41dd767ceaa40b8d76b06658b96f299492a0 (diff)
downloadbcm5719-llvm-322c127bee3f9efc0e9f78d3ff3957b60c653d20.tar.gz
bcm5719-llvm-322c127bee3f9efc0e9f78d3ff3957b60c653d20.zip
[ValueTracking] Add comment that CannotBeOrderedLessThanZero does the wrong thing for powi.
Summary: CannotBeOrderedLessThanZero(powi(x, exp)) returns true if CannotBeOrderedLessThanZero(x). But powi(-0, exp) is negative if exp is odd, so we actually want to return SignBitMustBeZero(x). Except that also isn't right, because we want to return true if x is NaN, even if x has a negative sign bit. What we really need in order to fix this is a consistent approach in this function to handling the sign bit of NaNs. Without this it's very difficult to say what the correct behavior here is. Reviewers: hfinkel, efriedma, sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D28927 llvm-svn: 293243
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ad4e668efbf..10bd640b46f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2602,6 +2602,11 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
const TargetLibraryInfo *TLI,
bool SignBitOnly,
unsigned Depth) {
+ // TODO: This function does not do the right thing when SignBitOnly is true
+ // and we're lowering to a hypothetical IEEE 754-compliant-but-evil platform
+ // which flips the sign bits of NaNs. See
+ // https://llvm.org/bugs/show_bug.cgi?id=31702.
+
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
return !CFP->getValueAPF().isNegative() ||
(!SignBitOnly && CFP->getValueAPF().isZero());
@@ -2678,8 +2683,22 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
if (Exponent->getBitWidth() <= 64 && Exponent->getSExtValue() % 2u == 0)
return true;
}
+ // TODO: This is not correct. Given that exp is an integer, here are the
+ // ways that pow can return a negative value:
+ //
+ // pow(x, exp) --> negative if exp is odd and x is negative.
+ // pow(-0, exp) --> -inf if exp is negative odd.
+ // pow(-0, exp) --> -0 if exp is positive odd.
+ // pow(-inf, exp) --> -0 if exp is negative odd.
+ // pow(-inf, exp) --> -inf if exp is positive odd.
+ //
+ // Therefore, if !SignBitOnly, we can return true if x >= +0 or x is NaN,
+ // but we must return false if x == -0. Unfortunately we do not currently
+ // have a way of expressing this constraint. See details in
+ // https://llvm.org/bugs/show_bug.cgi?id=31702.
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
Depth + 1);
+
case Intrinsic::fma:
case Intrinsic::fmuladd:
// x*x+y is non-negative if y is non-negative.
OpenPOWER on IntegriCloud