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 } }. */