https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88931

            Bug ID: 88931
           Summary: Failed to convert int128 to float/double with
                    round=FE_UPWARD/FE_TOWARDZERO
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libgcc
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hjl.tools at gmail dot com
  Target Milestone: ---

[hjl@gnu-cfl-1 float128-5]$ cat x.c
#include <fenv.h>
#include <stdio.h>
#include <quadmath.h>

#pragma STDC FENV_ACCESS ON
#define ROUNDING(r) { r, #r }

int
main (void)
{
  char buf[128];
  union
    {
      long long ll[2];
      __int128 q;
    } u = { 0xdLL, 0x8000000000000000LL };
  int i;
  struct
    {
      int r;
      const char *s;
    } round[] =
  {
    ROUNDING (FE_DOWNWARD),
    ROUNDING (FE_UPWARD),
    ROUNDING (FE_TOWARDZERO),
    ROUNDING (FE_TONEAREST)
  };
  for (i = 0; i < sizeof (round) / sizeof (round[0]); i++) {
    fesetround(round[i].r);
    float f = (float) u.q;
    double d = (double) u.q;
    __float128 q = (__float128) u.q;
    printf("fegetround=%d: %d, %s\n",
           fegetround(), round[i].r, round[i].s);
    printf("f=%f\t%x\n", f, *(int*)&f);
    printf("d=%lf\t%llx\n", d,  *(long long*)&d);
    quadmath_snprintf(buf, 128, "%Qf", 100, q);
    printf("q=%s\t%016llx%016llx\n",
           buf, *((long long *)&q + 1), *(long long *)&q);
  }
  return 0;
}
[hjl@gnu-cfl-1 float128-5]$ make
gcc -std=c99 -fno-strict-aliasing -g    -c -o x.o x.c
gcc -o x x.o -lm -lquadmath
./x
fegetround=1024: 1024, FE_DOWNWARD
f=-170141183460469231731687303715884105728.000000       ff000000
d=-170141183460469231731687303715884105728.000000       c7e0000000000000
q=-170141183460469231731687303715884105728.000000      
c07e0000000000000000000000000000
fegetround=2048: 2048, FE_UPWARD
f=-170141183460469231731687303715884105728.000000       ff000000
d=-170141183460469231731687303715884105728.000000       c7e0000000000000
q=-170141183460469231731687303715884089344.000000      
c07dffffffffffffffffffffffffffff
fegetround=3072: 3072, FE_TOWARDZERO
f=-170141183460469231731687303715884105728.000000       ff000000
d=-170141183460469231731687303715884105728.000000       c7e0000000000000
q=-170141183460469231731687303715884089344.000000      
c07dffffffffffffffffffffffffffff
fegetround=0: 0, FE_TONEAREST
f=-170141183460469231731687303715884105728.000000       ff000000
d=-170141183460469231731687303715884105728.000000       c7e0000000000000
q=-170141183460469231731687303715884105728.000000      
c07e0000000000000000000000000000
[hjl@gnu-cfl-1 float128-5]$ 

For FE_UPWARD and FE_TOWARDZERO, float should be feffffff and double
should be c7dfffffffffffff.

Reply via email to