https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11832

--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> ---
Note the testcase is flawed because c might point to b and thus the stores to
c[b] might clobber b itself.  Similar c might point to c itself and thus
clobber the pointer value.  This causes us to re-load both b and c after
each store.

Making b local and c a parameter avoids these issues:

int a, e;
void foo(unsigned char *c)
{
  int d = 13;
  int b = -1;
  switch (e) {
    case 1:
    b++; c[b] = (unsigned char)d;
    break;
    case 2:
    b++; c[b] = (unsigned char)d;
    b++; c[b] = (unsigned char)d;
    break;
    case 3:
    b++; c[b] = (unsigned char)d;
    b++; c[b] = (unsigned char)d;
    b++; c[b] = (unsigned char)d;
    break;
    default:
    a = 1;
    b++; c[b] = (unsigned char)d;
    b++; c[b] = (unsigned char)d;
    b++; c[b] = (unsigned char)d;
    b++; c[b] = (unsigned char)d;
  }
}

I have a patch to do some store merging during SSA code sinking but it doesn't
handle this case because the 1) the stores are ordered in the wrong way,
2) the CFG is not in proper form (I only handle common stores appearing in
all predecessors)

Reply via email to