https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117997
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Reduced testcase (again -O2 -fpie misbehaves, -O2 or -O2 -fpie -fno-optimize-crc is fine) below. While it is still quite large, most of it actually isn't executed at all, what misbehaves is the baz function (i.e. crc8 update) when filling the array, but strangely it doesn't misbehave if I just call it alone. __attribute__((noipa)) unsigned char foo (const unsigned char *data, unsigned int len) { __builtin_abort (); } __attribute__((noipa)) unsigned short bar (const unsigned char *data, unsigned int len) { __builtin_abort (); } static unsigned char baz (unsigned char byte, unsigned char crc) { unsigned int i; crc ^= byte; for (i = 0; i < 8; i++) crc = (crc << 1) ^ ((crc >> 7) ? 0x07 : 0); return crc; } static unsigned short qux (unsigned char byte, unsigned short crc) { unsigned int i; crc ^= byte << 8; for (i = 0; i < 8; i++) crc = (crc << 1) ^ ((crc >> 15) ? 0x8005 : 0); return crc; } __attribute__((noipa)) int corge (const unsigned char *data) { const unsigned char expected[] = { 0x00, 0x07, 0x1b, 0x48, 0xe3, 0xbc, 0x2f, 0xd8, 0x3e, 0x85, 0xa4, 0x44, 0xff, 0xd0, 0x14, 0x41, 0xb0, 0x6e, 0x73, 0x27, 0x99, 0xad, 0x28, 0xbd, 0x72, 0x16, 0x24, 0xbd, 0x6e, 0x5e, 0xc7, 0x06 }; for (int i = 0; i < 32; ++i) if (data[i] != expected[i]) __builtin_abort (); return 1; } static int garply (const unsigned char *data, unsigned long size) { unsigned int i; unsigned char crc0, crc1; crc0 = 0; crc1 = foo (data, 0); if (crc1 != crc0) return 0; for (i = 0; i < size; i++) { crc0 = baz (data[i], crc0); crc1 = foo (data, i + 1); if (crc1 != crc0) return 0; } return 1; } static int freddy (const unsigned char *data, unsigned long size) { unsigned int i; unsigned short crc0, crc1; crc0 = 0; crc1 = bar (data, 0); if (crc1 != crc0) return 0; for (i = 0; i < size; i++) { crc0 = qux (data[i], crc0); crc1 = bar (data, i + 1); if (crc1 != crc0) return 0; } return 1; } __attribute__((noipa)) int blah (void) { unsigned int i; unsigned char data[64] = { 0 }; for (i = 1; i < 64; i++) data[i] = baz (i % 256, data[i - 1]); if (corge (data)) return 0; if (!garply (data, 64)) return 1; if (!freddy (data, 64)) return 1; return 1; } int main () { if (blah ()) __builtin_abort (); }