diff options
author | Chris Lattner <sabre@nondot.org> | 2008-06-02 01:29:46 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-06-02 01:29:46 +0000 |
commit | 833f25d79ee28f1049f9177c3d2f4c9fbad6f643 (patch) | |
tree | a220de2e1a1ee0a4a134b3b2e5975267b3139c0b /lib/Analysis/ValueTracking.cpp | |
parent | 173234a68fb6ece106e77da443d87f09d5906cb9 (diff) |
move CannotBeNegativeZero to ValueTracking. Simplify some signbit comparisons.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index a35d625e31..2fe60907fb 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -707,3 +707,53 @@ unsigned llvm::ComputeNumSignBits(Value *V, TargetData *TD, unsigned Depth) { // shifting. We don't want to return '64' as for an i32 "0". return std::max(FirstAnswer, std::min(TyBits, Mask.countLeadingZeros())); } + +/// CannotBeNegativeZero - Return true if we can prove that the specified FP +/// value is never equal to -0.0. +/// +/// NOTE: this function will need to be revisited when we support non-default +/// rounding modes! +/// +bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) { + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) + return !CFP->getValueAPF().isNegZero(); + + if (Depth == 6) + return 1; // Limit search depth. + + const Instruction *I = dyn_cast<Instruction>(V); + if (I == 0) return false; + + // (add x, 0.0) is guaranteed to return +0.0, not -0.0. + if (I->getOpcode() == Instruction::Add && + isa<ConstantFP>(I->getOperand(1)) && + cast<ConstantFP>(I->getOperand(1))->isNullValue()) + return true; + + // sitofp and uitofp turn into +0.0 for zero. + if (isa<SIToFPInst>(I) || isa<UIToFPInst>(I)) + return true; + + if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) + // sqrt(-0.0) = -0.0, no other negative results are possible. + if (II->getIntrinsicID() == Intrinsic::sqrt) + return CannotBeNegativeZero(II->getOperand(1), Depth+1); + + if (const CallInst *CI = dyn_cast<CallInst>(I)) + if (const Function *F = CI->getCalledFunction()) { + if (F->isDeclaration()) { + switch (F->getNameLen()) { + case 3: // abs(x) != -0.0 + if (!strcmp(F->getNameStart(), "abs")) return true; + break; + case 4: // abs[lf](x) != -0.0 + if (!strcmp(F->getNameStart(), "absf")) return true; + if (!strcmp(F->getNameStart(), "absl")) return true; + break; + } + } + } + + return false; +} + |