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

--- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> ---
I bet you can't see the failures because they depend on fixes in a patch that
hasn't been committed yet:
  https://gcc.gnu.org/pipermail/gcc-patches/2021-November/583735.html

But I wonder if there actually is something else wrong besides the test making
bad assumptions.  I glossed over an important detail in the test and reduced it
too far to capture the difference between the or1k-elf and x86_64 IL.  This is
closer to what the test does:

extern char a[1];

int f (void);

int g (void)
{
  extern unsigned w;

  if (w < 5)
    w = 5;

  return __builtin_sprintf (a + 1, "%*i", w, f ());   <<< call f() to get value
}

The call to f() is what in x86_64 resets w's range (because w is extern and the
call to f() might overwrite it).  But with the or1k-elf target, that's not what
happens.  The IL shows that the call is made after the store to w and the value
used for the width in the sprintf() call is the one before the call.  That
seems like a bug, and that's the reason for the difference in the warning on
the two targets:

int g ()
{
  unsigned int w.0_1;
  int _3;
  int _9;
  unsigned int prephitmp_10;

  <bb 2> [local count: 1073741824]:
  w.0_1 = w;
  if (w.0_1 <= 4)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [local count: 536870913]:
  w = 5;

  <bb 4> [local count: 1073741824]:
  # prephitmp_10 = PHI <w.0_1(2), 5(3)>               <<< w used in sprintf()
  _3 = f ();                                          <<< call to f() might
clobber w
  _9 = __builtin_sprintf (&MEM <char[1]> [(void *)&a + 1B], "%*i",
prephitmp_10, _3);
  return _9;

}

The x86_64 IL looks correct:

  <bb 4> [local count: 1073741824]:
  _2 = f ();
  w.1_3 = w;
  _9 = __builtin_sprintf (&MEM <char[1]> [(void *)&a + 1B], "%*i", w.1_3, _2);
  return _9;

Reply via email to