# [llvm] r212638 - AArch64: Better codegen for storing to __fp16.

Stephen Canon scanon at apple.com
Thu Jul 10 12:18:33 PDT 2014

```> On Jul 10, 2014, at 1:02 PM, Tim Northover <t.p.northover at gmail.com> wrote:
>
>> Sort-of. It’s not wrong to go through float, but doing so does require care about rounding (which we weren’t doing).
>
> And vice-versa, surely? If we were asked in the IR to perform a double
> -> float -> fp16 conversion don't we have to do that unless we know
> the result isn't changed?
>
> Which is why I think this double-conversion has to be fixed in Clang:
> the input IR *is* saying to do it in two steps.

Tim’s right.  If we’re given e.g:

void foo(double x, __fp16 *p) {
*p = (float)x;
}

then we should* actually do the conversion in two steps, first to float, then to __fp16.

On the other hand:

void bar(double x, __fp16 *p) {
*p = x;
}

should* do the conversion with a single rounding (note, it need not be done in a single step to be done with a single rounding; it suffices to do double -> float -> __fp16 if the first conversion is done according to round-to-odd, a la arm64’s FCVTXN instruction; however, I suspect that we want to represent this at the IR level as a single conversion operation so that we can differentiate the two cases).

For an example of where the two functions differ, consider a double with the following significand in binary:

10000000000.1000000000000.0000000000000000000000001

(the “.”s indicate the rounding points for __fp16 and float).  When rounded directly from double to __fp16, this rounds up.  However, if it is rounded to float first and then to __fp16, it rounds *down* instead.

– Steve

(*) As Tim and I discussed off-list yesterday, __fp16 isn’t mentioned anywhere by C / C++, so there isn’t a strong standards requirement here.  However, in order for the type to be useful, we should attempt to have __fp16 conform to the IEEE-754 rules for the “binary16" interchange type, which includes getting these conversions “right” (i.e. conforming to the usual rules for conversions that apply to all FP types).

```