Skip to content

Commit 322c127

Browse files
author
Justin Lebar
committed
[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
1 parent cb9b41d commit 322c127

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2602,6 +2602,11 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
26022602
const TargetLibraryInfo *TLI,
26032603
bool SignBitOnly,
26042604
unsigned Depth) {
2605+
// TODO: This function does not do the right thing when SignBitOnly is true
2606+
// and we're lowering to a hypothetical IEEE 754-compliant-but-evil platform
2607+
// which flips the sign bits of NaNs. See
2608+
// https://llvm.org/bugs/show_bug.cgi?id=31702.
2609+
26052610
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
26062611
return !CFP->getValueAPF().isNegative() ||
26072612
(!SignBitOnly && CFP->getValueAPF().isZero());
@@ -2678,8 +2683,22 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
26782683
if (Exponent->getBitWidth() <= 64 && Exponent->getSExtValue() % 2u == 0)
26792684
return true;
26802685
}
2686+
// TODO: This is not correct. Given that exp is an integer, here are the
2687+
// ways that pow can return a negative value:
2688+
//
2689+
// pow(x, exp) --> negative if exp is odd and x is negative.
2690+
// pow(-0, exp) --> -inf if exp is negative odd.
2691+
// pow(-0, exp) --> -0 if exp is positive odd.
2692+
// pow(-inf, exp) --> -0 if exp is negative odd.
2693+
// pow(-inf, exp) --> -inf if exp is positive odd.
2694+
//
2695+
// Therefore, if !SignBitOnly, we can return true if x >= +0 or x is NaN,
2696+
// but we must return false if x == -0. Unfortunately we do not currently
2697+
// have a way of expressing this constraint. See details in
2698+
// https://llvm.org/bugs/show_bug.cgi?id=31702.
26812699
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
26822700
Depth + 1);
2701+
26832702
case Intrinsic::fma:
26842703
case Intrinsic::fmuladd:
26852704
// x*x+y is non-negative if y is non-negative.

0 commit comments

Comments
 (0)