From 7d187fdfdfcf16441c895625f2d947c7a09a0060 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 4 May 2018 07:30:50 +0000 Subject: [PATCH] re PR tree-optimization/85627 (ICE in update_phi_components in tree-complex.c) 2018-05-04 Richard Biener 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 | 11 ++++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/torture/pr85627.C | 33 +++++++++++ gcc/tree-complex.c | 81 +++++++++++++------------- gcc/tree.c | 6 +- 5 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr85627.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e769f54e6b..6ea25f8a9b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2018-05-04 Richard Biener + + 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 PR middle-end/85574 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e5784eb346..7bf4cad5fa8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-05-04 Richard Biener + + PR middle-end/85627 + * g++.dg/torture/pr85627.C: New testcase. + 2018-05-04 Richard Biener 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 index 00000000000..9be9a8cb9e6 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr85627.C @@ -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" } } */ diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 87e27aacb51..93f274cd213 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -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; + 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; - } - } + if (TREE_CODE_CLASS (code) == tcc_unary) + bl = UNINITIALIZED; + else if (ac == bc) + bl = al; else - al = bl = VARYING; + { + bl = find_lattice_value (bc); + if (bl == UNINITIALIZED) + 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); diff --git a/gcc/tree.c b/gcc/tree.c index b661d3d0dcd..77a73b4495e 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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); } }