This is an archive of the discontinued LLVM Phabricator instance.

ValueTracking: Teach isKnownNeverInfinity about rounding intrinsics
ClosedPublic

Authored by arsenm on Dec 5 2022, 5:29 AM.

Diff Detail

Event Timeline

arsenm created this revision.Dec 5 2022, 5:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 5 2022, 5:29 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
arsenm requested review of this revision.Dec 5 2022, 5:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 5 2022, 5:29 AM
Herald added a subscriber: wdng. · View Herald Transcript
sepavloff accepted this revision.Dec 8 2022, 2:37 AM

LGTM.

This revision is now accepted and ready to land.Dec 8 2022, 2:37 AM
kpn added a comment.Dec 8 2022, 5:41 AM

Are we certain that a value that is very close to infinity won't trip over into infinity after rounding?

arsenm added a comment.Dec 8 2022, 6:20 AM

Are we certain that a value that is very close to infinity won't trip over into infinity after rounding?

https://godbolt.org/z/54a737acd.

My man page for ceil states

SUSv2  and POSIX.1-2001 contain text about overflow (which might set errno to ERANGE, or raise an FE_OVERFLOW exception).  In
practice, the result cannot overflow on any current machine, so this error-handling stuff is just nonsense.  (More precisely,
overflow  can  happen  only  when  the  maximum  value  of the exponent is smaller than the number of mantissa bits.  For the
IEEE-754 standard 32-bit and 64-bit floating-point numbers the maximum value of the exponent is 128 (respectively, 1024), and
the number of mantissa bits is 24 (respectively, 53).)
kpn added a comment.Dec 8 2022, 10:06 AM

Assuming we don't have to worry about the new, 8 and 16 bit FP formats I'm happy to see this move forward.

Are we certain that a value that is very close to infinity won't trip over into infinity after rounding?

I'm thinking it might not be true for ppc_fp128--{largest_finite64, 0.75} should round into infinity I think? All of the other IEEE-like floating point types should have it be true, though--even e4m3 and e5m2 have largest_finite be an integer.

arsenm added a comment.Dec 9 2022, 9:31 AM

Are we certain that a value that is very close to infinity won't trip over into infinity after rounding?

I'm thinking it might not be true for ppc_fp128--{largest_finite64, 0.75} should round into infinity I think? All of the other IEEE-like floating point types should have it be true, though--even e4m3 and e5m2 have largest_finite be an integer.

What should I do here? How do I check this? godbolt seems to not support ppc execution, and I've had a real hard time finding any ppc f128 documentation

Are we certain that a value that is very close to infinity won't trip over into infinity after rounding?

I'm thinking it might not be true for ppc_fp128--{largest_finite64, 0.75} should round into infinity I think? All of the other IEEE-like floating point types should have it be true, though--even e4m3 and e5m2 have largest_finite be an integer.

What should I do here? How do I check this? godbolt seems to not support ppc execution, and I've had a real hard time finding any ppc f128 documentation

PPC uses double double encoding (https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format), in which a number is represented by a sum of two double precision numbers, where the second just keeps additional mantissa bits. Total number of mantissa bits in ppc_fp128 is about 107 bits. Exponent range is the same as for double numbers: 2^-1022 to 2^1023. So large numbers (above 2^108) are always integers, they do not need rounding and the result of ceil, floor etc is the argument.

PPC uses double double encoding (https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format), in which a number is represented by a sum of two double precision numbers, where the second just keeps additional mantissa bits. Total number of mantissa bits in ppc_fp128 is about 107 bits. Exponent range is the same as for double numbers: 2^-1022 to 2^1023. So large numbers (above 2^108) are always integers, they do not need rounding and the result of ceil, floor etc is the argument.

My understanding here is that the number of mantissa bits is effectively dynamic, since you could combine a large exponent (e.g., 2^1023) in the first number and a tiny exponent (e.g., 2^-50) in the second one, and all the mantissa bits in the middle would be implied 0. But I have no actual practical experience with ppc_fp128, and documentation for these kinds of things isn't great.

arsenm added a subscriber: nemanjai.Dec 9 2022, 1:35 PM

Are we certain that a value that is very close to infinity won't trip over into infinity after rounding?

I'm thinking it might not be true for ppc_fp128--{largest_finite64, 0.75} should round into infinity I think? All of the other IEEE-like floating point types should have it be true, though--even e4m3 and e5m2 have largest_finite be an integer.

What should I do here? How do I check this? godbolt seems to not support ppc execution, and I've had a real hard time finding any ppc f128 documentation

cc @nemanjai What is the ppcf128 behavior for these functions?

sepavloff requested changes to this revision.Dec 13 2022, 9:36 PM

PPC uses double double encoding (https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format), in which a number is represented by a sum of two double precision numbers, where the second just keeps additional mantissa bits. Total number of mantissa bits in ppc_fp128 is about 107 bits. Exponent range is the same as for double numbers: 2^-1022 to 2^1023. So large numbers (above 2^108) are always integers, they do not need rounding and the result of ceil, floor etc is the argument.

My understanding here is that the number of mantissa bits is effectively dynamic, since you could combine a large exponent (e.g., 2^1023) in the first number and a tiny exponent (e.g., 2^-50) in the second one, and all the mantissa bits in the middle would be implied 0. But I have no actual practical experience with ppc_fp128, and documentation for these kinds of things isn't great.

It seems you are right. What I spoke about is actually the case of semPPCDoubleDoubleLegacy, which indeed has 106 bits of mantissa. So only Intrinsic::trunc works as expected for all FP formats, for other rounding functions we should check if the semantics is not semPPCDoubleDouble.

This revision now requires changes to proceed.Dec 13 2022, 9:36 PM
arsenm updated this revision to Diff 482898.Dec 14 2022, 9:33 AM

Special case ppcfp128. Not sure if we need to exclude bfloat16 since it's exponent bits is larger than mantissa

Special case ppcfp128. Not sure if we need to exclude bfloat16 since it's exponent bits is larger than mantissa

bfloat16 has the same exponent range as float, that is from -126 to 127. If number of mantissa bit were larger than 127, there would be problems. Actually large bfloat16 values are integers.

llvm/include/llvm/IR/Type.h
189–194

What you need for this patch is availability of fixed size mantissa. Custom short FP types, like 8 and 16 bit floats may be non-IEEE in strict sense but they still provide definite number of mantissa bits.

I would propose to use isPPC_FP128Ty to filter out indeterminate precision formats or, if you want, to define a predicate like:

/// Returns true if this floating-point type represents unevaluated sum of shorter floating-point values.
bool isMultiWordFPType() const {
    return getTypeID() == PPC_FP128TyID;
}

If someone uses additional types with such property in their LLVM-based compilers, they can extend this function.

arsenm added inline comments.Dec 14 2022, 11:12 AM
llvm/include/llvm/IR/Type.h
189–194

Word is a bit overloaded, and someone might read this as word == 4 bytes

sepavloff added inline comments.Dec 14 2022, 8:52 PM
llvm/include/llvm/IR/Type.h
189–194

It is from "Handbook of Floating-Point Arithmetic" (https://link.springer.com/book/10.1007/978-0-8176-4705-6), chapter 14. You may use 'hasIndeterminatePrecision` or choose any name you like, if you prefer a separate predicate.

arsenm updated this revision to Diff 483539.Dec 16 2022, 7:33 AM

Rename predicate

sepavloff added inline comments.Dec 19 2022, 2:18 AM
llvm/test/Transforms/InstSimplify/floating-point-compare.ll
1554

IIUC this case should not be folded, only trunc is folded for ppc_fp128?

arsenm updated this revision to Diff 483924.Dec 19 2022, 5:27 AM

Regenerate test checks

This revision is now accepted and ready to land.Dec 20 2022, 7:39 AM
jcranmer-intel added inline comments.Dec 20 2022, 8:09 AM
llvm/include/llvm/IR/Type.h
188–194

IMHO, "unit" is a slightly better name, but I think more important than getting the name right is clarifying what is meant in the documentation comment.