re PR tree-optimization/85627 (ICE in update_phi_components in tree-complex.c)
authorRichard Biener <rguenther@suse.de>
Fri, 4 May 2018 07:30:50 +0000 (07:30 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 4 May 2018 07:30:50 +0000 (07:30 +0000)
2018-05-04  Richard Biener  <rguenther@suse.de>

PR middle-end/85627
* tree-complex.c (update_complex_assignment): We are always in SSA form.
(expand_complex_div_wide): Likewise.
(expand_complex_operations_1): Likewise.
(expand_complex_libcall): Preserve EH info of the original stmt.
(tree_lower_complex): Handle removed blocks.
* tree.c (build_common_builtin_nodes): Do not set ECF_NOTRHOW
on complex multiplication and division libcall builtins.

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

From-SVN: r259923

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

index 3e769f54e6b8caec9ed7d40452ed5085035276de..6ea25f8a9b530606bbd78a31c6c2677efe57f3a6 100644 (file)
@@ -1,3 +1,14 @@
+2018-05-04  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/85627
+       * tree-complex.c (update_complex_assignment): We are always in SSA form.
+       (expand_complex_div_wide): Likewise.
+       (expand_complex_operations_1): Likewise.
+       (expand_complex_libcall): Preserve EH info of the original stmt.
+       (tree_lower_complex): Handle removed blocks.
+       * tree.c (build_common_builtin_nodes): Do not set ECF_NOTRHOW
+       on complex multiplication and division libcall builtins.
+
 2018-05-04  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/85574
index 9e5784eb346f0905f2ba85f23cebe93572d2c715..7bf4cad5fa8e77ed6ccb2b9f34fd74c43eaa32c9 100644 (file)
@@ -1,3 +1,8 @@
+2018-05-04  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/85627
+       * g++.dg/torture/pr85627.C: New testcase.
+
 2018-05-04  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/85574
diff --git a/gcc/testsuite/g++.dg/torture/pr85627.C b/gcc/testsuite/g++.dg/torture/pr85627.C
new file mode 100644 (file)
index 0000000..9be9a8c
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-additional-options "-fnon-call-exceptions -fdump-tree-optimized" } */
+
+__complex double
+foo (__complex double a, __complex double b)
+{
+  __complex res = a;
+  try {
+      res = a * b;
+  }
+  catch (...) {
+      res = b;
+  }
+  return res;
+}
+
+__complex double
+bar (__complex double a, __complex double b)
+{
+  __complex res = a;
+  try {
+      res = a / b;
+  }
+  catch (...) {
+      res = b;
+  }
+  return res;
+}
+
+/* Verify EH is preserved by complex lowering.  */
+
+/* { dg-final { scan-tree-dump-times "__cxa_begin_catch" 2 "optimized" } } */
index 87e27aacb517c52924edafb8fd0916a08b1589fd..93f274cd213cdbe5ce552f8c8ccf11eb2a46352f 100644 (file)
@@ -703,8 +703,7 @@ update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
   if (maybe_clean_eh_stmt (stmt))
     gimple_purge_dead_eh_edges (gimple_bb (stmt));
 
-  if (gimple_in_ssa_p (cfun))
-    update_complex_components (gsi, gsi_stmt (*gsi), r, i);
+  update_complex_components (gsi, gsi_stmt (*gsi), r, i);
 }
 
 
@@ -1006,37 +1005,44 @@ expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai,
   else
     gcc_unreachable ();
   fn = builtin_decl_explicit (bcode);
-
   stmt = gimple_build_call (fn, 4, ar, ai, br, bi);
 
-
   if (inplace_p)
     {
       gimple *old_stmt = gsi_stmt (*gsi);
+      gimple_call_set_nothrow (stmt, !stmt_could_throw_p (old_stmt));
       lhs = gimple_assign_lhs (old_stmt);
       gimple_call_set_lhs (stmt, lhs);
-      update_stmt (stmt);
-      gsi_replace (gsi, stmt, false);
-
-      if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
-       gimple_purge_dead_eh_edges (gsi_bb (*gsi));
+      gsi_replace (gsi, stmt, true);
 
       type = TREE_TYPE (type);
-      update_complex_components (gsi, stmt,
-                                 build1 (REALPART_EXPR, type, lhs),
-                                 build1 (IMAGPART_EXPR, type, lhs));
+      if (stmt_can_throw_internal (stmt))
+       {
+         edge_iterator ei;
+         edge e;
+         FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
+             if (!(e->flags & EDGE_EH))
+               break;
+         basic_block bb = split_edge (e);
+         gimple_stmt_iterator gsi2 = gsi_start_bb (bb);
+         update_complex_components (&gsi2, stmt,
+                                    build1 (REALPART_EXPR, type, lhs),
+                                    build1 (IMAGPART_EXPR, type, lhs));
+         return NULL_TREE;
+       }
+      else
+       update_complex_components (gsi, stmt,
+                                  build1 (REALPART_EXPR, type, lhs),
+                                  build1 (IMAGPART_EXPR, type, lhs));
       SSA_NAME_DEF_STMT (lhs) = stmt;
       return NULL_TREE;
     }
 
-  lhs = create_tmp_var (type);
+  gimple_call_set_nothrow (stmt, true);
+  lhs = make_ssa_name (type);
   gimple_call_set_lhs (stmt, lhs);
-
-  lhs = make_ssa_name (lhs, stmt);
-  gimple_call_set_lhs (stmt, lhs);
-
-  update_stmt (stmt);
   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+
   return lhs;
 }
 
@@ -1265,14 +1271,8 @@ expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
       gimple *stmt;
       tree cond, tmp;
 
-      tmp = create_tmp_var (boolean_type_node);
+      tmp = make_ssa_name (boolean_type_node);
       stmt = gimple_build_assign (tmp, compare);
-      if (gimple_in_ssa_p (cfun))
-       {
-         tmp = make_ssa_name (tmp, stmt);
-         gimple_assign_set_lhs (stmt, tmp);
-       }
-
       gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
 
       cond = fold_build2_loc (gimple_location (stmt),
@@ -1698,25 +1698,20 @@ expand_complex_operations_1 (gimple_stmt_iterator *gsi)
   else
     br = bi = NULL_TREE;
 
-  if (gimple_in_ssa_p (cfun))
+  al = find_lattice_value (ac);
+  if (al == UNINITIALIZED)
+    al = VARYING;
+
+  if (TREE_CODE_CLASS (code) == tcc_unary)
+    bl = UNINITIALIZED;
+  else if (ac == bc)
+    bl = al;
+  else
     {
-      al = find_lattice_value (ac);
-      if (al == UNINITIALIZED)
-       al = VARYING;
-
-      if (TREE_CODE_CLASS (code) == tcc_unary)
-       bl = UNINITIALIZED;
-      else if (ac == bc)
-       bl = al;
-      else
-       {
-         bl = find_lattice_value (bc);
-         if (bl == UNINITIALIZED)
-           bl = VARYING;
-       }
+      bl = find_lattice_value (bc);
+      if (bl == UNINITIALIZED)
+       bl = VARYING;
     }
-  else
-    al = bl = VARYING;
 
   switch (code)
     {
@@ -1788,6 +1783,8 @@ tree_lower_complex (void)
   for (i = 0; i < n_bbs; i++)
     {
       bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
+      if (!bb)
+       continue;
       update_phi_components (bb);
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        expand_complex_operations_1 (&gsi);
index b661d3d0dcd0c816329b72f60c300fff2b856372..77a73b4495e2ddde469c0d95f234348a19830ce1 100644 (file)
@@ -10386,17 +10386,19 @@ build_common_builtin_nodes (void)
          *q = TOLOWER (*p);
        *q = '\0';
 
+       /* For -ftrapping-math these should throw from a former
+          -fnon-call-exception stmt.  */
        built_in_names[mcode] = concat (prefix, "mul", mode_name_buf, "3",
                                        NULL);
         local_define_builtin (built_in_names[mcode], ftype, mcode,
                              built_in_names[mcode],
-                             ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+                             ECF_CONST | ECF_LEAF);
 
        built_in_names[dcode] = concat (prefix, "div", mode_name_buf, "3",
                                        NULL);
         local_define_builtin (built_in_names[dcode], ftype, dcode,
                              built_in_names[dcode],
-                             ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+                             ECF_CONST | ECF_LEAF);
       }
   }