aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ac83869..2b8b1ef 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3523,11 +3523,20 @@ bool llvm::isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI,
return isKnownNeverInfinity(Inst->getOperand(1), TLI, Depth + 1) &&
isKnownNeverInfinity(Inst->getOperand(2), TLI, Depth + 1);
}
- case Instruction::UIToFP:
- // If the input type fits into the floating type the result is finite.
- return ilogb(APFloat::getLargest(
- Inst->getType()->getScalarType()->getFltSemantics())) >=
- (int)Inst->getOperand(0)->getType()->getScalarSizeInBits();
+ case Instruction::SIToFP:
+ case Instruction::UIToFP: {
+ // Get width of largest magnitude integer (remove a bit if signed).
+ // This still works for a signed minimum value because the largest FP
+ // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
+ int IntSize = Inst->getOperand(0)->getType()->getScalarSizeInBits();
+ if (Inst->getOpcode() == Instruction::SIToFP)
+ --IntSize;
+
+ // If the exponent of the largest finite FP value can hold the largest
+ // integer, the result of the cast must be finite.
+ Type *FPTy = Inst->getType()->getScalarType();
+ return ilogb(APFloat::getLargest(FPTy->getFltSemantics())) >= IntSize;
+ }
default:
break;
}