On Tue, 12 Sep 2017, Richard Biener wrote:

> 
> This is the one with the folding fix...

And it didn't work out (the comment before the changed line even
explains...).  Thus I'll do the following.

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

Richard.

2017-09-13  Richard Biener  <rguent...@suse.de>

        PR middle-end/82128
        * gimple-fold.c (gimple_fold_call): Update SSA name in-place to
        default-def to avoid breaking iterator update with the weird
        interaction with cgraph_update_edges_for_call_stmt_node.

        * g++.dg/pr82128.C: New testcase.

Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   (revision 252060)
+++ gcc/gimple-fold.c   (working copy)
@@ -3862,24 +3862,18 @@ gimple_fold_call (gimple_stmt_iterator *
                  tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
                  gimple *new_stmt = gimple_build_call (fndecl, 0);
                  gimple_set_location (new_stmt, gimple_location (stmt));
+                 /* If the call had a SSA name as lhs morph that into
+                    an uninitialized value.  */
                  if (lhs && TREE_CODE (lhs) == SSA_NAME)
                    {
                      tree var = create_tmp_var (TREE_TYPE (lhs));
-                     tree def = get_or_create_ssa_default_def (cfun, var);
-
-                     /* To satisfy condition for
-                        cgraph_update_edges_for_call_stmt_node,
-                        we need to preserve GIMPLE_CALL statement
-                        at position of GSI iterator.  */
-                     update_call_from_tree (gsi, def);
-                     gsi_insert_before (gsi, new_stmt, GSI_NEW_STMT);
-                   }
-                 else
-                   {
-                     gimple_set_vuse (new_stmt, gimple_vuse (stmt));
-                     gimple_set_vdef (new_stmt, gimple_vdef (stmt));
-                     gsi_replace (gsi, new_stmt, false);
+                     SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
+                     SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
+                     set_ssa_default_def (cfun, var, lhs);
                    }
+                 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
+                 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+                 gsi_replace (gsi, new_stmt, false);
                  return true;
                }
            }
Index: gcc/testsuite/g++.dg/pr82128.C
===================================================================
--- gcc/testsuite/g++.dg/pr82128.C      (revision 0)
+++ gcc/testsuite/g++.dg/pr82128.C      (working copy)
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-options "-O3 -fno-tree-forwprop" }
+
+class A {
+      virtual unsigned long m_fn1() const;
+        virtual int &m_fn2(unsigned long) const;
+};
+class C : A {
+public:
+      int &m_fn2(unsigned long) const;
+        unsigned long m_fn1() const;
+};
+class B {
+      void m_fn3(const A &, const int &, const C &, int &) const;
+};
+void B::m_fn3(const A &, const int &, const C &, int &) const {
+      C &a(a);
+        for (long b = 0; a.m_fn1(); b++)
+             a.m_fn2(0);
+}

Reply via email to