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

            Bug ID: 119014
           Summary: Extending _Float16 constant at compile and run time
                    differs
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: stefansf at gcc dot gnu.org
  Target Milestone: ---

__attribute__ ((noipa)) _Float16
test (void)
{
  return 42.42f16;
}

int
main (void)
{
  _Float16 x = test ();
  if (x != 42.42f16)
    __builtin_abort ();
  return 0;
}

Naively I would expect that the condition evaluates to true.  However, on
x86_64 with -mno-avx512fp16 this evaluates to false.  It seems to me that the
front end chose to statically extend 42.42f16 to a float which differs from
extending the result of test() at runtime.  Optimized tree dump:

__attribute__((noipa, noinline, noclone, no_icf))
_Float16 test ()
{
  <bb 2> [local count: 1073741824]:
  return 4.240625e+1;

}

int main ()
{
  _Float16 x;
  float _1;

  <bb 2> [local count: 1073741824]:
  x_4 = test ();
  _1 = (float) x_4;
  if (_1 != 4.24199981689453125e+1)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073741824]:
  return 0;

}

The float cast results in a call to __extendhfsf2 where the result is unequal
to 4.24199981689453125e+1.

Changing the initial example slightly by not comparing directly with a constant
but assigning it first to variable y:

__attribute__ ((noipa)) _Float16
test (void)
{
  return 42.42f16;
}

int
main (void)
{
  _Float16 x = test ();
  _Float16 y = 42.42f16;
  if (x != y)
    __builtin_abort ();
  return 0;
}

gives us the expected result:

__attribute__((noipa, noinline, noclone, no_icf))
_Float16 test ()
{
  <bb 2> [local count: 1073741824]:
  return 4.240625e+1;

}

int main ()
{
  _Float16 x;

  <bb 2> [local count: 1073741824]:
  x_3 = test ();
  if (x_3 != 4.240625e+1)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073741824]:
  return 0;

}

I'm not sure whether this is "expected" and is covered by some C/IEEE-754
rules.  Maybe someone can shed some light on it?

Reply via email to