This fixes the PR.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2016-09-20  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/77646
        * tree-ssa-sccvn.c (visit_reference_op_call): Always value-number
        a VDEF.

        * gcc.dg/torture/pr77646.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c        (revision 240255)
--- gcc/tree-ssa-sccvn.c        (working copy)
*************** visit_reference_op_call (tree lhs, gcall
*** 3470,3475 ****
--- 3577,3586 ----
      {
        if (vnresult->result_vdef && vdef)
        changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
+       else if (vdef)
+       /* If the call was discovered to be pure or const reflect
+          that as far as possible.  */
+       changed |= set_ssa_val_to (vdef, vuse_ssa_val (gimple_vuse (stmt)));
  
        if (!vnresult->result && lhs)
        vnresult->result = lhs;
Index: gcc/testsuite/gcc.dg/torture/pr77646.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr77646.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr77646.c      (working copy)
***************
*** 0 ****
--- 1,21 ----
+ /* { dg-do compile } */
+ 
+ struct e {
+     int (*f)();
+     void (*g)();
+ } * c;
+ int a;
+ void *h();
+ typedef struct { struct e j; } k;
+ int l() { return a; }
+ const struct e b = {l};
+ void m()
+ {
+   k *d = h();
+   d->j = b;
+   c = (struct e *)d;
+   struct e *i = c;
+   if (i->f(c))
+     while (i->f(c))
+       i->g();
+ }

Reply via email to