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

--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #11)
> (In reply to Hans-Peter Nilsson from comment #10)
> > (In reply to Richard Biener from comment #9)
> > > gcc.dg/tree-ssa/ssa-fre-104.c has been XFAILed.
> > 
> > Any obvious target-specific reason for this to XPASS on cris-elf, m68k-linux
> > and pru-elf?
> > 
> > (per recent gcc-testresults posts)
> 
> Most likely because
> int e[][1] = {0, 0, 0, 0, 0, 1};
> 
> Is done as a copy from a const static decl vs done via stores to e[i][0].
> 
> Maybe do s/5/2/ and change the number of elements down to 3 for the array
> and you will hit the issue again on those targets.

Huh, most likely, but I don't see how that would help ... that should
make it _fail_ to optimize this ...

So checking cris-elf I see

  <bb 2> :
  e[0][0] = 0;
  e[1][0] = 0;
  e[2][0] = 0;
  e[3][0] = 0;
  e[4][0] = 0;
  e[5][0] = 1;

  <bb 3> :
  bar25_ ();
  a.0_1 = a;
  _2 = e[5][a.0_1];
  if (_2 != 0)
    goto <bb 5>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 4> :
  a.1_3 = a;
  e[a.1_3][0] = 0;
  foo ();
  goto <bb 3>; [INV]

before FRE, the same IL as on x86_64.  A FRE dump diff reveals

 Setting value number of a.0_1 to a.0_1 (changed)
 Making available beyond BB3 a.0_1 for value a.0_1
 Value numbering stmt = _2 = e[5][a.0_1];
-Skipping possible redundant definition e[5][0] = 1;
-Setting value number of _2 to _2 (changed)
-Using extra use virtual operand .MEM_5
-Making available beyond BB3 _2 for value _2
+Setting value number of _2 to 1 (changed)

that's exactly the reason for the regression - we're now trying to skip
the definition on x86_64.  And we can do so there because of the alignment
of 'e' which on cris seems to be less than the size of 'int' (int is
aligned to 1 byte but its size is still 4 bytes).

So

int a;
int *b = &a;
int **c = &b;
int d;
void bar25_(void);
void foo(void);
int main() {
  int __attribute__((aligned(sizeof(int)))) e[][1] = {0, 0, 0, 0, 0, 1};
  for (;;) {
    bar25_();
    /* We should optimistically treat a == 0 because of the bounds of
       the object.  */
    if (e[5][a])
      break;
    e[a][0] = 0;
    foo();
  }
  *c = &d;
}

also fails on cris.  Let me update the testcase.

Reply via email to