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

--- Comment #2 from vries at gcc dot gnu.org ---
(In reply to vries from comment #1)
> Created attachment 38141 [details]
> updated test-case
> 
> Fails with -O1, passes with -O2.
> 
> The problem is that this loop nest:
> ... 
>   for (zh = 0; zh < 2; ++zh)
>     for (ro = 0; ro < 3; ++ro)
>       yu[ro][0] = yu[zh + 1][0];
> ...

Unrolled, that looks like:

  /* yu == { { 1 }, { 2 }, { 3 }, { 4 } }.  */

  yu[0][0] = yu[1][0]; /* zh == 0, ro == 0.  */

  /* yu == { { 2 }, { 2 }, { 3 }, { 4 } }.  */

  yu[1][0] = yu[1][0]; /* zh == 0, ro == 1.  */

  /* yu == { { 2 }, { 2 }, { 3 }, { 4 } }.  */

  yu[2][0] = yu[1][0]; /* zh == 0, ro == 2.  */

  /* yu == { { 2 }, { 2 }, { 2 }, { 4 } }.  */

  yu[0][0] = yu[2][0]; /* zh == 1, ro == 0.  */

  /* yu == { { 2 }, { 2 }, { 2 }, { 4 } }.  */

  yu[1][0] = yu[2][0]; /* zh == 1, ro == 1.  */

  /* yu == { { 2 }, { 2 }, { 2 }, { 4 } }.  */

  yu[2][0] = yu[2][0]; /* zh == 1, ro == 2.  */

  /* yu == { { 2 }, { 2 }, { 2 }, { 4 } }.  */


> is rewritten into this loop nest, which has different semantics:
> ...
>   for (ro = 0; ro < 3; ++ro)
>     for (zh = 0; zh < 2; ++zh)
>       yu[ro][0] = yu[zh + 1][0];
> ...

and unrolled, this looks like:

  /* yu == { { 1 }, { 2 }, { 3 }, { 4 } }.  */

  yu[0][0] = yu[1][0]; /* zh == 0, ro == 0.  */

  /* yu == { { 2 }, { 2 }, { 3 }, { 4 } }.  */

  yu[0][0] = yu[2][0]; /* zh == 1, ro == 0.  */

  /* yu == { { 3 }, { 2 }, { 3 }, { 4 } }.  */

  yu[1][0] = yu[1][0]; /* zh == 0, ro == 1.  */

  /* yu == { { 3 }, { 2 }, { 3 }, { 4 } }.  */

  yu[1][0] = yu[2][0]; /* zh == 1, ro == 1.  */

  /* yu == { { 3 }, { 3 }, { 3 }, { 4 } }.  */

  yu[2][0] = yu[1][0]; /* zh == 0, ro == 2.  */

  /* yu == { { 3 }, { 3 }, { 3 }, { 4 } }.  */

  yu[2][0] = yu[2][0]; /* zh == 1, ro == 2.  */

  /* yu == { { 3 }, { 3 }, { 3 }, { 4 } }.  */

Reply via email to