------- Comment #3 from rguenth at gcc dot gnu dot org  2009-10-11 11:56 -------
The key is IMHO that the inner loop does not have its loop header copied.
This confuses SCEV enough to think that a = (unsigned short)a is always
executed.  LIM is necessary to promote all the memory to SSA names, the
interesting CHREC that gets wrong is

<bb 3>:
..
  a_lsm.6_18 = 0x0fffffff3;
  goto <bb 5>;

<bb 4>:
...
  a.1_2 = a_lsm.6_15;
  D.2006_3 = (short unsigned int) a.1_2;
  a.2_4 = (unsigned int) D.2006_3;
  a_lsm.6_20 = a.2_4;

<bb 5>:
  # a_lsm.6_15 = PHI <a_lsm.6_18(3), a_lsm.6_20(4)>
...
  a.1_1 = a_lsm.6_15;
  if (a.1_1 == 0)
    goto <bb 4>;
  else
    goto <bb 6>;

 <bb 6>:
...
-  # a_lsm.6_27 = PHI <a_lsm.6_15(5)>


 <bb 8>:
-  # a_lsm.6_28 = PHI <a_lsm.6_27(6)>
-  a = a_lsm.6_28;
+  a = 65523;

where interestingly a_lsm.6_15 isn't computed wrong.


Testcase, fails at -Os:

extern void abort (void);

unsigned int a;
int b, c;

void
foo (void)
{
  b = 0;
  do {
    for (a = -13; a == 0; a = (unsigned short)a)
      c = 1;
    b++;
  } while (b == 0);
}

int
main ()
{
  foo ();
  if (a != -13)
    abort ();
  return 0;
}


-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |spop at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41497

Reply via email to