/* PR middle-end/78257 - missing memcmp optimization with constant arrays { dg-do compile } { dg-options "-O -Wall -fdump-tree-optimized" } { dg-skip-if "missing data representation" { "pdp11-*-*" } } { dg-skip-if "test assumes structs are not packed" { default_packed } } */ #define offsetof(T, m) __builtin_offsetof (T, m) typedef __INT8_TYPE__ int8_t; typedef __INT16_TYPE__ int16_t; typedef __INT32_TYPE__ int32_t; typedef __INT64_TYPE__ int64_t; typedef __SIZE_TYPE__ size_t; extern int memcmp (const void*, const void*, size_t); const int32_t ia4[4] = { 0x11121314, 0x21222324, 0x31323334, 0x41424344 }; const int32_t ia4_des[4] = { [2] = 0x31323334, [0] = 0x11121314, 0x21222324, [3] = 0x41424344 }; const char ia4_rep[] = { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ "\x11\x12\x13\x14" "\x21\x22\x23\x24" "\x31\x32\x33\x34" "\x41\x42\x43\x44" #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ "\x14\x13\x12\x11" "\x24\x23\x22\x21" "\x34\x33\x32\x31" "\x44\x43\x42\x41" #endif }; void eq_ia4 (void) { int n = 0, b = sizeof ia4; const char *p = (const char*)ia4, *q = ia4_rep; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); n += memcmp (p + 8, q + 8, b - 8); n += memcmp (p + 9, q + 9, b - 9); n += memcmp (p + 10, q + 10, b - 10); n += memcmp (p + 11, q + 11, b - 11); n += memcmp (p + 12, q + 12, b - 12); n += memcmp (p + 13, q + 13, b - 13); n += memcmp (p + 14, q + 14, b - 14); n += memcmp (p + 15, q + 15, b - 15); n += memcmp (p + 16, q + 16, b - 16); p = (const char*)ia4_des; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); n += memcmp (p + 8, q + 8, b - 8); n += memcmp (p + 9, q + 9, b - 9); n += memcmp (p + 10, q + 10, b - 10); n += memcmp (p + 11, q + 11, b - 11); n += memcmp (p + 12, q + 12, b - 12); n += memcmp (p + 13, q + 13, b - 13); n += memcmp (p + 14, q + 14, b - 14); n += memcmp (p + 15, q + 15, b - 15); n += memcmp (p + 16, q + 16, b - 16); if (n != 0) __builtin_abort (); } const float fa4[4] = { 1.0, 2.0, 3.0, 4.0 }; const float fa4_des[4] = { [0] = fa4[0], [1] = 2.0, [2] = fa4[2], [3] = 4.0 }; void eq_fa4 (void) { int n = 0, b = sizeof fa4; const char *p = (const char*)fa4, *q = (const char*)fa4_des; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); n += memcmp (p + 8, q + 8, b - 8); n += memcmp (p + 9, q + 9, b - 9); n += memcmp (p + 10, q + 10, b - 10); n += memcmp (p + 11, q + 11, b - 11); n += memcmp (p + 12, q + 12, b - 12); n += memcmp (p + 13, q + 13, b - 13); n += memcmp (p + 14, q + 14, b - 14); n += memcmp (p + 15, q + 15, b - 15); n += memcmp (p + 16, q + 16, b - 16); if (n != 0) __builtin_abort (); } /* Verify "greater than" comparison with the difference in the last byte. */ const char ia4_xrep_16[sizeof ia4] = { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42 #endif }; void gt_ia4 (void) { int n = 0, b = sizeof ia4; const char *p = (const char*)ia4, *q = ia4_xrep_16; n += 0 < memcmp (p, q, b); n += 0 < memcmp (p + 1, q + 1, b - 1); n += 0 < memcmp (p + 2, q + 2, b - 2); n += 0 < memcmp (p + 3, q + 3, b - 3); n += 0 < memcmp (p + 4, q + 4, b - 4); n += 0 < memcmp (p + 5, q + 5, b - 5); n += 0 < memcmp (p + 6, q + 6, b - 6); n += 0 < memcmp (p + 7, q + 7, b - 7); n += 0 < memcmp (p + 8, q + 8, b - 8); n += 0 < memcmp (p + 9, q + 9, b - 9); n += 0 < memcmp (p + 10, q + 10, b - 10); n += 0 < memcmp (p + 11, q + 11, b - 11); n += 0 < memcmp (p + 12, q + 12, b - 12); n += 0 < memcmp (p + 13, q + 13, b - 13); n += 0 < memcmp (p + 14, q + 14, b - 14); n += 0 < memcmp (p + 15, q + 15, b - 15); if (n != 16) __builtin_abort (); } struct S8_16_32 { int8_t i8; int16_t i16; int32_t i32; }; _Static_assert (sizeof (struct S8_16_32) == 8); const struct S8_16_32 s8_16_32 = { 1, 0x2122, 0x31323334 }; const struct S8_16_32 s8_16_32_des = { .i8 = 1, .i16 = 0x2122, .i32 = 0x31323334 }; const char s8_16_32_rep[] = { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 1, 0, 0x21, 0x22, 0x31, 0x32, 0x33, 0x34 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 1, 0, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31 #endif }; void eq_s8_16_32 (void) { int n = 0, b = sizeof s8_16_32; const char *p = (char*)&s8_16_32, *q = s8_16_32_rep; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); p = (char*)&s8_16_32_des; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); if (n != 0) __builtin_abort (); } struct S8_16_32_64 { /* 0 */ int8_t i8; /* 1 */ int8_t: 1; /* 2 */ int16_t i16; /* 4 */ int32_t: 1; /* 8 */ int32_t i32; /* 12 */ int32_t: 1; /* 16 */ int64_t i64; /* 24 */ int8_t: 0; }; _Static_assert (offsetof (struct S8_16_32_64, i16) == 2); _Static_assert (offsetof (struct S8_16_32_64, i32) == 8); _Static_assert (offsetof (struct S8_16_32_64, i64) == 16); _Static_assert (sizeof (struct S8_16_32_64) == 24); const struct S8_16_32_64 s8_16_32_64 = { 1, 0x2122, 0x31323334, 0x4142434445464748LLU }; const char s8_16_32_64_rep[sizeof s8_16_32_64] = { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ "\x01" "\x00" "\x21\x22" "\x00\x00\x00\x00" "\x31\x32\x33\x34" "\x00\x00\x00\x00" "\x41\x42\x43\x44\x45\x46\x47\x48" #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ "\x01" "\x00" "\x22\x21" "\x00\x00\x00\x00" "\x34\x33\x32\x31" "\x00\x00\x00\x00" "\x48\x47\x46\x45\x44\x43\x42\x41" #endif }; const struct S8_16_32_64 s8_16_32_64_des = { .i64 = 0x4142434445464748LLU, .i16 = 0x2122, .i32 = 0x31323334, .i8 = 1 }; void eq_8_16_32_64 (void) { int n = 0, b = sizeof s8_16_32_64; const char *p = (char*)&s8_16_32_64, *q = s8_16_32_64_rep; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); n += memcmp (p + 8, q + 8, b - 8); n += memcmp (p + 9, q + 9, b - 9); n += memcmp (p + 10, q + 10, b - 10); n += memcmp (p + 11, q + 11, b - 11); n += memcmp (p + 12, q + 12, b - 12); n += memcmp (p + 13, q + 13, b - 13); n += memcmp (p + 14, q + 14, b - 14); n += memcmp (p + 15, q + 15, b - 15); n += memcmp (p + 16, q + 16, b - 16); n += memcmp (p + 17, q + 17, b - 17); n += memcmp (p + 18, q + 18, b - 18); n += memcmp (p + 19, q + 19, b - 19); n += memcmp (p + 20, q + 20, b - 20); n += memcmp (p + 21, q + 21, b - 21); n += memcmp (p + 22, q + 22, b - 22); n += memcmp (p + 23, q + 23, b - 23); p = (char*)&s8_16_32_64_des; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); n += memcmp (p + 8, q + 8, b - 8); n += memcmp (p + 9, q + 9, b - 9); n += memcmp (p + 10, q + 10, b - 10); n += memcmp (p + 11, q + 11, b - 11); n += memcmp (p + 12, q + 12, b - 12); n += memcmp (p + 13, q + 13, b - 13); n += memcmp (p + 14, q + 14, b - 14); n += memcmp (p + 15, q + 15, b - 15); n += memcmp (p + 16, q + 16, b - 16); n += memcmp (p + 17, q + 17, b - 17); n += memcmp (p + 18, q + 18, b - 18); n += memcmp (p + 19, q + 19, b - 19); n += memcmp (p + 20, q + 20, b - 20); n += memcmp (p + 21, q + 21, b - 21); n += memcmp (p + 22, q + 22, b - 22); n += memcmp (p + 23, q + 23, b - 23); if (n != 0) __builtin_abort (); } struct S64_x_3 { int64_t i64a[3]; }; _Static_assert (sizeof (struct S64_x_3) == 24); const struct S64_x_3 s64_x_3 = { { 0x0000000021220001LLU, 0x0000000031323334LLU, 0x4142434445464748LLU } }; const char s64_x_3_rep[sizeof s64_x_3] = { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ "\x00\x00\x00\x00\x21\x22\x00\x01" "\x00\x00\x00\x00\x31\x32\x33\x34" "\x41\x42\x43\x44\x45\x46\x47\x48" #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ "\x01\x00\x22\x21\x00\x00\x00\x00" "\x34\x33\x32\x31\x00\x00\x00\x00" "\x48\x47\x46\x45\x44\x43\x42\x41" #endif }; void eq_64_x_3 (void) { int n = 0, b = sizeof s8_16_32_64; const char *p = (char*)&s8_16_32_64, *q = s64_x_3_rep; n += memcmp (p, q, b); n += memcmp (p + 1, q + 1, b - 1); n += memcmp (p + 2, q + 2, b - 2); n += memcmp (p + 3, q + 3, b - 3); n += memcmp (p + 4, q + 4, b - 4); n += memcmp (p + 5, q + 5, b - 5); n += memcmp (p + 6, q + 6, b - 6); n += memcmp (p + 7, q + 7, b - 7); n += memcmp (p + 8, q + 8, b - 8); n += memcmp (p + 9, q + 9, b - 9); n += memcmp (p + 10, q + 10, b - 10); n += memcmp (p + 11, q + 11, b - 11); n += memcmp (p + 12, q + 12, b - 12); n += memcmp (p + 13, q + 13, b - 13); n += memcmp (p + 14, q + 14, b - 14); n += memcmp (p + 15, q + 15, b - 15); n += memcmp (p + 16, q + 16, b - 16); n += memcmp (p + 17, q + 17, b - 17); n += memcmp (p + 18, q + 18, b - 18); n += memcmp (p + 19, q + 19, b - 19); n += memcmp (p + 20, q + 20, b - 20); n += memcmp (p + 21, q + 21, b - 21); n += memcmp (p + 22, q + 22, b - 22); n += memcmp (p + 23, q + 23, b - 23); if (n != 0) __builtin_abort (); } /* { dg-final { scan-tree-dump-not "abort" "optimized" } } */