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

Mikhail Maltsev <miyuki at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
      Known to work|                            |4.8.4
           Keywords|                            |wrong-code
   Last reconfirmed|                            |2015-05-24
                 CC|                            |miyuki at gcc dot gnu.org
     Ever confirmed|0                           |1
            Summary|wrong code at -O3 on        |[4.9.2/5/6 Regression]
                   |x86_64-linux-gnu            |wrong code at -O3 on
                   |                            |x86_64-linux-gnu
      Known to fail|                            |4.9.2, 5.1.0, 6.0

--- Comment #1 from Mikhail Maltsev <miyuki at gcc dot gnu.org> ---
The testcase can be simplified a bit (I eliminated variable c and moved array a
inside main, so it's now local).

struct S
{
  int f0;
  int f1;
};

int b;

int main ()
{
    struct S a[2] = { 0 };
    struct S d = { 0, 1 };
    for (b = 0; b < 2; b++) {
        a[b] = d;
        d = a[0];
    }
    if (d.f1 != 1)
        __builtin_abort ();
}

Wrong transformation is made in predictive commoning pass (the program compiled
with -O3 -fno-predictive-commoning does not abort). The store d.f1 = a[0].f1;
is assumed to be independent of the previous store to a[b] (which is obviously
wrong) and it is hoisted out of the loop.

I think the reason is that find_data_references_in_stmt or some related
function misenterprets MEM[(struct S[2] *)&a + 4B] as some object that does not
alias with MEM[(struct S *)&a]'s SCEV.
By the way, the expression itself looks strange: struct S * should be "a", not
"&a".

(Data Dep:
#(Data Ref:
#  bb: 3
#  stmt: MEM[(struct S *)_4 + 4B] = d$f1_7;
#  ref: MEM[(struct S *)_4 + 4B];
#  base_object: MEM[(struct S *)&a];
#  Access function 0: {4B, +, 8}_1
#)
#(Data Ref:
#  bb: 3
#  stmt: d$f1_16 = MEM[(struct S[2] *)&a + 4B];
#  ref: MEM[(struct S[2] *)&a + 4B];
#  base_object: MEM[(struct S[2] *)&a + 4B];
#)
    (no dependence)
)

If I scalarize the assignment d = a[0] (I mean, in the source), the bug
disappears.

Reply via email to