https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78257
--- Comment #5 from Martin Liška <marxin at gcc dot gnu.org> --- (In reply to Martin Sebor from comment #4) > Created attachment 40008 [details] > Very lightly tested patch. > > The attached (only superficially tested) patch changes fold_bultin_memcmp to > fold the comparison over the length of the arrays rather than just the first > pair of bytes. Does it look reasonable? I played a bit with the patch and it's nice that it can handle(In reply to Martin Sebor from comment #4) > Created attachment 40008 [details] > Very lightly tested patch. > > The attached (only superficially tested) patch changes fold_bultin_memcmp to > fold the comparison over the length of the arrays rather than just the first > pair of bytes. Does it look reasonable? I played a bit with the patch and it ICEs with: #include <assert.h> #include <stdio.h> const int i[] = { 16843009 }; const char k[] = {1, 1, 1, 1}; int main() { unsigned test = sizeof(i) * 1; assert (__builtin_memcmp (i, k, test) == 0); return 0; } and without an optimization level, it can produce tons of assembly code: #include <assert.h> #include <stdio.h> #define ctor(N) {N, N, N, N, N, N, N, N, N, N, N, N} const int i[] = ctor(123456); const int k[] = ctor(123456); int main() { assert (__builtin_memcmp (i, k, sizeof i) == 0); return 0; } folding2.c.004t.gimple: .... i.1_1 = &i; _2 = MEM[(const unsigned char * {ref-all})i.1_1]; k.2_3 = &k; _4 = MEM[(const unsigned char * {ref-all})k.2_3]; if (_2 == _4) goto <D.2268>; else goto <D.2269>; <D.2268>: _5 = &i + 1; _6 = *_5; _7 = &k + 1; _8 = *_7; if (_6 == _8) goto <D.2271>; else goto <D.2272>; <D.2271>: _9 = &i + 2; _10 = *_9; _11 = &k + 2; _12 = *_11; if (_10 == _12) goto <D.2274>; else goto <D.2275>; <D.2274>: _13 = &i + 3; _14 = *_13; _15 = &k + 3; _16 = *_15; if (_14 == _16) goto <D.2277>; else goto <D.2278>; <D.2277>: _17 = &i + 4; _18 = *_17; _19 = &k + 4; _20 = *_19; Martin