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

            Bug ID: 126469
           Summary: (double)float1 CMP (double)float2 into float1 CMP
                    float2 picks the wrong comparison type
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

__attribute__((noipa)) int feq (__bf16 b, _Float16 h)
{ float x = (float) b; float y = (float) h; return x == y; }
__attribute__((noipa)) int flt (__bf16 b, _Float16 h)
{ float x = (float) b; float y = (float) h; return x < y; }
__attribute__((noipa)) int geq (_Float16 h, __bf16 b)
{ float y = (float) h; float x = (float) b; return y == x; }
__attribute__((noipa)) int ggt (_Float16 h, __bf16 b)
{ float y = (float) h; float x = (float) b; return y > x; }

__attribute__((noipa)) __bf16 mkb (float f) { return (__bf16) f; }
__attribute__((noipa)) _Float16 mkh (float f) { return (_Float16) f; }

int main (void)
{
  /* Case A: bf16 exponent range exceeds _Float16 range.  */
  __bf16 b1 = mkb (3.0e38f);                 /* finite, 3.00406e+38 */
  _Float16 h1 = mkh (__builtin_inff ());     /* +Inf */
  __builtin_printf ("A: (float)b=%g (float)h=%g eq=%d lt=%d\n",
                    (double)(float) b1, (double)(float) h1,
                    feq (b1, h1), flt (b1, h1));
  if (feq (b1, h1) != 0) __builtin_abort ();
  if (flt (b1, h1) != 1) __builtin_abort ();

  /* Case B: _Float16 significand exceeds bf16 significand.  */
  __bf16 b2 = mkb (1.0f);
  _Float16 h2 = mkh (1.0f + 1.0f / 1024.0f); /* 1.0009765625, exact in fp16 */
  __builtin_printf ("B: (float)h=%.10g (float)b=%.10g eq=%d gt=%d\n",
                    (double)(float) h2, (double)(float) b2,
                    geq (h2, b2), ggt (h2, b2));
  if (geq (h2, b2) != 0) __builtin_abort ();
  if (ggt (h2, b2) != 1) __builtin_abort ();
  return 0;
}

passes at -O0 and aborts at -O1 and works fine with Clang.
__bf16 and _Float16 both have element_precision 16 but neither format contains
the other, so one operand is converted lossily

Reply via email to