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

Reply via email to