Skip to content

Commit 6966859

Browse files
committed
ValueTracking: Implement computeKnownFPClass for fpext
1 parent 384a8dd commit 6966859

File tree

4 files changed

+85
-47
lines changed

4 files changed

+85
-47
lines changed

llvm/include/llvm/ADT/APFloat.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ struct APFloatBase {
273273
static unsigned int semanticsSizeInBits(const fltSemantics &);
274274
static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool);
275275

276+
// Returns true if any number described by \p Src can be precisely represented
277+
// by a normal (not subnormal) value in \p Dst.
278+
static bool isRepresentableAsNormalIn(const fltSemantics &Src,
279+
const fltSemantics &Dst);
280+
276281
/// Returns the size of the floating point number (in bits) in the given
277282
/// semantics.
278283
static unsigned getSizeInBits(const fltSemantics &Sem);

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4679,6 +4679,25 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
46794679

46804680
break;
46814681
}
4682+
case Instruction::FPExt: {
4683+
// Infinity, nan and zero propagate from source.
4684+
computeKnownFPClass(Op->getOperand(0), DemandedElts, InterestedClasses,
4685+
Known, Depth + 1, Q, TLI);
4686+
4687+
const fltSemantics &DstTy =
4688+
Op->getType()->getScalarType()->getFltSemantics();
4689+
const fltSemantics &SrcTy =
4690+
Op->getOperand(0)->getType()->getScalarType()->getFltSemantics();
4691+
4692+
// All subnormal inputs should be in the normal range in the result type.
4693+
if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy))
4694+
Known.knownNot(fcSubnormal);
4695+
4696+
// Sign bit of a nan isn't guaranteed.
4697+
if (!Known.isKnownNeverNaN())
4698+
Known.SignBit = std::nullopt;
4699+
break;
4700+
}
46824701
case Instruction::FPTrunc: {
46834702
if ((InterestedClasses & fcNan) == fcNone)
46844703
break;

llvm/lib/Support/APFloat.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,20 @@ unsigned int APFloatBase::semanticsIntSizeInBits(const fltSemantics &semantics,
308308
return MinBitWidth;
309309
}
310310

311+
bool APFloatBase::isRepresentableAsNormalIn(const fltSemantics &Src,
312+
const fltSemantics &Dst) {
313+
// Exponent range must be larger.
314+
if (Src.maxExponent >= Dst.maxExponent || Src.minExponent <= Dst.minExponent)
315+
return false;
316+
317+
// If the mantissa is long enough, the result value could still be denormal
318+
// with a larger exponent range.
319+
//
320+
// FIXME: This condition is probably not accurate but also shouldn't be a
321+
// practical concern with existing types.
322+
return Dst.precision >= Src.precision;
323+
}
324+
311325
unsigned APFloatBase::getSizeInBits(const fltSemantics &Sem) {
312326
return Sem.sizeInBits;
313327
}

0 commit comments

Comments
 (0)