aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Analysis/ValueTracking.h7
-rw-r--r--lib/Analysis/ValueTracking.cpp50
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp56
3 files changed, 59 insertions, 54 deletions
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index d07e890..ca8d3e3 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -28,6 +28,9 @@ namespace llvm {
APInt &KnownOne, TargetData *TD = 0,
unsigned Depth = 0);
+ /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
+ /// this predicate to simplify operations downstream. Mask is known to be
+ /// zero for bits that V cannot have.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
TargetData *TD = 0, unsigned Depth = 0);
@@ -43,6 +46,10 @@ namespace llvm {
unsigned ComputeNumSignBits(Value *Op, TargetData *TD = 0,
unsigned Depth = 0);
+ /// CannotBeNegativeZero - Return true if we can prove that the specified FP
+ /// value is never equal to -0.0.
+ ///
+ bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
} // end namespace llvm
#endif
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index a35d625..2fe6090 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;
+}
+
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 05d935e..516841a 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -1839,50 +1839,6 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
}
-/// CannotBeNegativeZero - Return true if we can prove that the specified FP
-/// value is never equal to -0.0.
-///
-/// Note that this function will need to be revisited when we support nondefault
-/// rounding modes!
-///
-static bool CannotBeNegativeZero(const Value *V) {
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V))
- return !CFP->getValueAPF().isNegZero();
-
- if (const Instruction *I = dyn_cast<Instruction>(V)) {
- // (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))
- if (II->getIntrinsicID() == Intrinsic::sqrt)
- return CannotBeNegativeZero(II->getOperand(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;
-}
-
/// WillNotOverflowSignedAdd - Return true if we can prove that:
/// (sext (add LHS, RHS)) === (add (sext LHS), (sext RHS))
/// This basically requires proving that the add in the original type would not
@@ -2268,13 +2224,6 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
return Changed ? &I : 0;
}
-// isSignBit - Return true if the value represented by the constant only has the
-// highest order bit set.
-static bool isSignBit(ConstantInt *CI) {
- uint32_t NumBits = CI->getType()->getPrimitiveSizeInBits();
- return CI->getValue() == APInt::getSignBit(NumBits);
-}
-
Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -2460,8 +2409,7 @@ static bool isSignBitCheck(ICmpInst::Predicate pred, ConstantInt *RHS,
case ICmpInst::ICMP_UGE:
// True if LHS u>= RHS and RHS == high-bit-mask (2^7, 2^15, 2^31, etc)
TrueIfSigned = true;
- return RHS->getValue() ==
- APInt::getSignBit(RHS->getType()->getPrimitiveSizeInBits());
+ return RHS->getValue().isSignBit();
default:
return false;
}
@@ -6124,7 +6072,7 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
Constant::getNullValue(RHS->getType()));
// Replace (and X, (1 << size(X)-1) != 0) with x s< 0
- if (isSignBit(BOC)) {
+ if (BOC->getValue().isSignBit()) {
Value *X = BO->getOperand(0);
Constant *Zero = Constant::getNullValue(X->getType());
ICmpInst::Predicate pred = isICMP_NE ?