This is an archive of the discontinued LLVM Phabricator instance.

Improve the semantics ``fptrunc``
AbandonedPublic

Authored by delcypher on Feb 16 2016, 10:18 AM.

Details

Summary

Improve the semantics fptrunc. In r246792 I made it so
that how inexact results are computed are undefined. This seems
unnecessarily under specified. For example an implementation could be to return
undef for every value that cannot be represented exactly.

It is highly unlikely that anyone would want that so instead

  • Define the possible values that could be returned when a value given to fptrunc cannot be exactly represented in the result type ty2. The possible values returned cover all possible IEEE-754 rounding modes because we explicitly do not define which of the possible value out of the possible values is chosen. For example Round to nearest even either returns the predecessor, truncated or successor value.
  • Drop the discussion of what happens when a value cannot fit in type being cast to (i.e. ty2), previously the result was undefined. Instead the discussion of how to handle values that cannot be exactly represented covers this. This means that result is now defined.

Diff Detail

Event Timeline

delcypher updated this revision to Diff 48079.Feb 16 2016, 10:18 AM
delcypher retitled this revision from to Improve the semantics ``fptrunc``.
delcypher updated this object.
mehdi_amini added inline comments.
docs/LangRef.rst
7572

What does truncation bring here considering you're already covering predecessor and successor?

7573

s/predecesor/successor/

sunfish edited edge metadata.Feb 16 2016, 10:25 AM

This level of specificity feels out of place on fptrunc, given that LLVM doesn't mention IEEE 754 or specify its rounding behavior for its floating point instructions in general.

delcypher added inline comments.Feb 16 2016, 12:51 PM
docs/LangRef.rst
7572

Oops. Yes you're right. I'll fix that.

delcypher updated this revision to Diff 48098.Feb 16 2016, 1:00 PM
delcypher edited edge metadata.

Drop "predecessor" as one of the possible values returned by fptrunc is the conversion is not exact. We don't need it to do rounding.

delcypher marked 2 inline comments as done.Feb 16 2016, 1:00 PM
delcypher marked an inline comment as done.Feb 16 2016, 1:01 PM

Mark done

Your last change seems wrong to me, you dropped predecessor and kept rounding to zero. The problem is that rounding up and rounding to zero is the same for negative number.
What about being less specific and saying:

If the real number (``R``) represented by ``value`` cannot be exactly
represented using the :ref:`floating point <t_floating>` type ``ty2``, then the
value returned is rounded (in an undefined direction), or any of the
special values in ``ty2`` (e.g. +/- infinity, +/- zero and NaN). The method for
choosing which of these values to return is undefined.

CC: Steve Canon who may be able to help on a desirable wording.

This level of specificity feels out of place on fptrunc, given that LLVM doesn't mention IEEE 754 or specify its rounding behavior for its floating point instructions in general.

@sunfish What I've added is not specific to IEEE-754 rounding modes (there's no mention of it in the text I've added). My comments do note that the proposed semantics for fptrunc cover all the IEEE-754 rounding modes however but the point I was trying to make here is that the proposed semantics allow all the IEEE 754 rounding modes, the semantics also allow for rounding modes that are not part of IEEE-754 so there is nothing IEEE 754 specific here. The proposed semantics for handling values that can't be exactly represented basically cover all the way you might implement a reasonable rounding function.

It is indeed true that llvm instructions do not mention rounding modes but this seems like an oversight.

In D17296#353871, @joker.eph wrote:

Your last change seems wrong to me, you dropped predecessor and kept rounding to zero. The problem is that rounding up and rounding to zero is the same for negative number.
What about being less specific and saying:

If the real number (``R``) represented by ``value`` cannot be exactly
represented using the :ref:`floating point <t_floating>` type ``ty2``, then the
value returned is rounded (in an undefined direction), or any of the
special values in ``ty2`` (e.g. +/- infinity, +/- zero and NaN). The method for
choosing which of these values to return is undefined.

CC: Steve Canon who may be able to help on a desirable wording.

@joker.eph You're completely right. I'm very glad I added you a reviewer! Hopefully one day I'll stop making stupid mistakes like that, but today is not one of these days.

Your suggestion of not specifying the rounding direction is certainly one option. I'll go with that for now.

delcypher updated this revision to Diff 48101.Feb 16 2016, 1:26 PM

Don't mention successor/predecessor just say rounded in an undefined direction.

It LGTM now.
sunfish: does it still look too specific to you? Mentioning that an unspecified rounding can occur does not seem too much to me.

@joker.eph
By the way I also am aware I need to fix the example underneath the semantics. I'd also like to add a few more. I'll do this bit soon.

Non-IEEE-754 platforms do not all have infinities and sometimes do something different things on overflow. The current text gives such platforms a fair amount of flexibility. The proposed change restricts such platforms. Is this intended?

Also, the proposed change says that [+-]ininty, [+-]zero, and NaN may be returned from any inexact conversion. Is that really intended? It seems like this would significantly compromise the advantage sought here.

delcypher updated this revision to Diff 48259.Feb 17 2016, 4:21 PM

Go back to using "predecessor" and "successor", rather than "rounded in an unspecified direction". Rounding could be misinterpreted as we didn't state how far we round (e.g. we could skip several successors). Also note that the special values of type `ty2` might not exist.

sunfish resigned from this revision.Feb 17 2016, 5:08 PM
sunfish removed a reviewer: sunfish.

In addition to the practical concern I raised above, the proposed text is not conforming to the C or C++ standards. Here's a quote from C++ [conv.double], describing inexact conversions:

If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values.

The C standard has similar language. The proposed text here permits any inexact conversion to return 0 (among other things).

silvas resigned from this revision.Jul 8 2016, 11:42 PM
silvas removed a reviewer: silvas.
delcypher abandoned this revision.Jun 14 2018, 9:23 AM