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.