re PR tree-optimization/63476 (ICE: tree check: expected ssa_name, have var_decl...
authorRichard Biener <rguenther@suse.de>
Fri, 10 Oct 2014 11:04:39 +0000 (11:04 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 10 Oct 2014 11:04:39 +0000 (11:04 +0000)
2014-10-10  Richard Biener  <rguenther@suse.de>

PR tree-optimization/63476
* tree-ssa-pre.c (struct bb_bitmap_sets): Add vop_on_exit member.
(BB_LIVE_VOP_ON_EXIT): New define.
(create_expression_by_pieces): Assign VUSEs to stmts.
(compute_avail): Track BB_LIVE_VOP_ON_EXIT.
(pass_pre::execute): Assert virtual SSA form is up-to-date
after insertion.

* g++.dg/torture/pr63476.C: New testcase.

From-SVN: r216065

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr63476.C [new file with mode: 0644]
gcc/tree-ssa-pre.c

index 90fd7b56a749cafef4d840eee205106fdb7bb823..dbee77683b7eb8ae802d53183aed985fdd17257c 100644 (file)
@@ -1,3 +1,13 @@
+2014-10-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/63476
+       * tree-ssa-pre.c (struct bb_bitmap_sets): Add vop_on_exit member.
+       (BB_LIVE_VOP_ON_EXIT): New define.
+       (create_expression_by_pieces): Assign VUSEs to stmts.
+       (compute_avail): Track BB_LIVE_VOP_ON_EXIT.
+       (pass_pre::execute): Assert virtual SSA form is up-to-date
+       after insertion.
+
 2014-10-10  Eric Botcazou  <ebotcazou@adacore.com>
 
        * lra-assigns.c (assign_by_spills): Error out on spill failure.
index 13a553e9ba650a35946669a99d1fd614f814ee7b..2ed4d4a06124f53144440eef50867e9715730490 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/63476
+       * g++.dg/torture/pr63476.C: New testcase.
+
 2014-10-10  Tobias Burnus  <burnus@net-b.de>
 
        * gfortran.dg/implicit_16.f90: New.
diff --git a/gcc/testsuite/g++.dg/torture/pr63476.C b/gcc/testsuite/g++.dg/torture/pr63476.C
new file mode 100644 (file)
index 0000000..75ecc37
--- /dev/null
@@ -0,0 +1,39 @@
+// { dg-do compile }
+// { dg-additional-options "-std=gnu++11" }
+
+enum class nsresult;
+class A;
+class B
+{
+public:
+    B (int);
+    A *operator->();
+};
+class C
+{
+};
+class A
+{
+public:
+    virtual nsresult AddObserver (const char *, C *, bool) = 0;
+};
+class D : A
+{
+  nsresult
+      AddObserver (const char *p1, C *p2, bool p3)
+       {
+         AddObserver (p1, p2, p3);
+       }
+};
+char *prefList[]{};
+class F : C
+{
+  nsresult Install ();
+};
+nsresult
+F::Install ()
+{
+  B branch = 0;
+  for (int i;;)
+    branch->AddObserver (prefList[i], this, false);
+}
index cbbd422043329080ff12aafda0f74b15cac19e26..a447c1e4f06d974353f10538455f8bb0f640be08 100644 (file)
@@ -423,6 +423,9 @@ typedef struct bb_bitmap_sets
   /* A cache for value_dies_in_block_x.  */
   bitmap expr_dies;
 
+  /* The live virtual operand on successor edges.  */
+  tree vop_on_exit;
+
   /* True if we have visited this block during ANTIC calculation.  */
   unsigned int visited : 1;
 
@@ -440,6 +443,7 @@ typedef struct bb_bitmap_sets
 #define EXPR_DIES(BB)  ((bb_value_sets_t) ((BB)->aux))->expr_dies
 #define BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited
 #define BB_MAY_NOTRETURN(BB) ((bb_value_sets_t) ((BB)->aux))->contains_may_not_return_call
+#define BB_LIVE_VOP_ON_EXIT(BB) ((bb_value_sets_t) ((BB)->aux))->vop_on_exit
 
 
 /* Basic block list in postorder.  */
@@ -2886,12 +2890,15 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
              bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
              bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
            }
+
+         gimple_set_vuse (stmt, BB_LIVE_VOP_ON_EXIT (block));
        }
       gimple_seq_add_seq (stmts, forced_stmts);
     }
 
   name = make_temp_ssa_name (exprtype, NULL, "pretmp");
   newstmt = gimple_build_assign (name, folded);
+  gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
   gimple_set_plf (newstmt, NECESSARY, false);
 
   gimple_seq_add_stmt (stmts, newstmt);
@@ -3593,6 +3600,9 @@ compute_avail (void)
        son = next_dom_son (CDI_DOMINATORS, son))
     worklist[sp++] = son;
 
+  BB_LIVE_VOP_ON_EXIT (ENTRY_BLOCK_PTR_FOR_FN (cfun))
+    = ssa_default_def (cfun, gimple_vop (cfun));
+
   /* Loop until the worklist is empty.  */
   while (sp)
     {
@@ -3607,7 +3617,10 @@ compute_avail (void)
         its immediate dominator.  */
       dom = get_immediate_dominator (CDI_DOMINATORS, block);
       if (dom)
-       bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
+       {
+         bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
+         BB_LIVE_VOP_ON_EXIT (block) = BB_LIVE_VOP_ON_EXIT (dom);
+       }
 
       /* Generate values for PHI nodes.  */
       for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -3617,7 +3630,10 @@ compute_avail (void)
          /* We have no need for virtual phis, as they don't represent
             actual computations.  */
          if (virtual_operand_p (result))
-           continue;
+           {
+             BB_LIVE_VOP_ON_EXIT (block) = result;
+             continue;
+           }
 
          pre_expr e = get_or_alloc_expr_for_name (result);
          add_to_value (get_expr_value_id (e), e);
@@ -3661,6 +3677,9 @@ compute_avail (void)
              bitmap_value_insert_into_set (AVAIL_OUT (block), e);
            }
 
+         if (gimple_vdef (stmt))
+           BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt);
+
          if (gimple_has_side_effects (stmt)
              || stmt_could_throw_p (stmt)
              || is_gimple_debug (stmt))
@@ -4758,6 +4777,10 @@ pass_pre::execute (function *fun)
   remove_fake_exit_edges ();
   gsi_commit_edge_inserts ();
 
+  /* Eliminate folds statements which might (should not...) end up
+     not keeping virtual operands up-to-date.  */
+  gcc_assert (!need_ssa_update_p (fun));
+
   /* Remove all the redundant expressions.  */
   todo |= eliminate (true);