> I'm not opposed to merging the test change, but I couldn't figure out
> where in C the implicit conversion was coming from: as far as I can
> tell the macros don't introduce any (it's "return _float16 *
> _float16"), I'd had the patch open since last night but couldn't
> figure it out.
> 
> We get a bunch of half->single->half converting in the generated
> assembly that smelled like we had a bug somewhere else, sorry if I'm
> just missing something...

Yes, good point, my explanation was wrong again.

What really (TM) happens is that the equality comparison, in presence
of _Float16 emulation(!), performs an extension to float/double for its
arguments.

So
  if (res != r * q)
is
  if ((float)res (float)!= (float)(r * q))

Now, (r * q) is also implicitly computed in float.  Because the
comparison requires a float argument, there is no intermediate conversion
back to _Float16 and the value is more accurate than it would be in
_Float16.
res, however, despite being calculated in float as well, is converted
to _Float16 for the function return or rather the assignment to "res".
Therefore it is less accurate than (r * q) and the comparison fails.

So, what would also help, even though it's not obvious at first
sight is:

     TYPE res = reduc_plus_##TYPE (a, b);       \
-    if (res != r * q)          \
+    TYPE ref = r * q;                          \
+    if (res != ref)                            \
       __builtin_abort ();                      \
   }

This does not happen with proper _zfh because the operations are done
in _Float16 precision then.  BTW such kinds of non-obvious problems
are the reason why I split off _zvfh run tests into separate files
right away.

Regards
 Robin

Reply via email to