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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2023-01-25
                 CC|                            |aldyh at gcc dot gnu.org,
                   |                            |amacleod at redhat dot com
   Target Milestone|---                         |13.0
     Ever confirmed|0                           |1
           Priority|P3                          |P1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
stdarg.h isn't needed, so:
__attribute__((noipa)) void
bar (const char *cp, unsigned long size, char sign, int dsgn)
{
  if (__builtin_strcmp (cp, "ZERO") != 0 || size != 4 || sign != '-' || dsgn !=
1)
    __builtin_abort ();
}

__attribute__((noipa)) void
foo (int x, int ch, double d)
{
  const char *cp = "";
  unsigned long size = 0;
  char sign = '\0';
  switch (x)
    {
    case 42:
      if (__builtin_isinf (d))
        {
          if (d < 0)
            sign = '-';
          cp = "Inf";
          size = 3;
          break;
        }
      if (__builtin_isnan (d))
        {
          cp = "NaN";
          size = 3;
          break;
        }
      if (d < 0)
        {
          d = -d;
          sign = '-';
        }
      else if (d == 0.0 && __builtin_signbit (d))
        sign = '-';
      else
        sign = '\0';
      if (ch == 'a' || ch == 'A')
        {
          union U { long long l; double d; } u;
          int dsgn;
          u.d = d;
          if (u.l < 0)
            {
              dsgn = 1;
              u.l &= 0x7fffffffffffffffLL;
            }
          else
            dsgn = 0;
          if (__builtin_isinf (d))
            {
              cp = "INF";
              size = 3;
            }
          else if (__builtin_isnan (d))
            {
              cp = "NAN";
              size = 3;
            }
          else if (d == 0)
            {
              cp = "ZERO";
              size = 4;
            }
          else
            {
              cp = "WRONG";
              size = 5;
            }
          bar (cp, size, sign, dsgn);
        }
    }
}

int
main ()
{
  foo (42, 'a', -0.0);
  return 0;
}

The testcase is hand-written from what I see in
https://github.com/ruby/ruby/blob/a528908271c678360d2d8ca232c178e7cdd340b4/vsnprintf.c#L529
https://github.com/ruby/ruby/blob/a528908271c678360d2d8ca232c178e7cdd340b4/vsnprintf.c#L1229
https://github.com/ruby/ruby/blob/a528908271c678360d2d8ca232c178e7cdd340b4/missing/dtoa.c#L3387
where hdtoa is inlined into cvt which is inlined into vfprintf.  This reduced
testcase reproduces on x86_64-linux too.

Reply via email to