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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Further reduced:
__attribute__((noipa)) int
foo (const void *x)
{
  unsigned short b;
  __builtin_memcpy (&b, x, sizeof (short));
  if ((b & 15) != 8)
    return 1;
  if ((((unsigned char) b) >> 4) > 7)
    return 1;
  return 0;
}

int
main ()
{
  unsigned char a[8] = { 0x78, 0x78 };
  if (sizeof (short) == 2 && foo (a) != 0)
    __builtin_abort ();
}

Both (b & 15) != 8 and (((unsigned char) b) >> 4) > 7 tests actually only care
about the first byte (on little endian), and the second could be simplified to
(b & 128) != 0.
So I think both tests actually can be combined into (b & 143) != 8.
But instead of that ifcombine combines that to
optimizing two comparisons to (_8 & 143) == 8 && (_9 & 15) == 0
where _8 is the low byte and _9 is the high byte.  The old tests weren't
checking anything from the high byte before.

Reply via email to