aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr85627.C33
-rw-r--r--gcc/tree-complex.c81
-rw-r--r--gcc/tree.c6
5 files changed, 92 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3e769f5..6ea25f8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
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
* fold-const.c (negate_expr_p): Restrict negation of operand
zero of a division to when we know that can happen without
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9e5784e..7bf4cad 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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
* gcc.dg/torture/pr85574.c: New testcase.
* gcc.dg/torture/pr57656.c: Use dg-additional-options.
diff --git a/gcc/testsuite/g++.dg/torture/pr85627.C b/gcc/testsuite/g++.dg/torture/pr85627.C
new file mode 100644
index 0000000..9be9a8c
--- /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 87e27aa..93f274c 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;
+
+ 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);
diff --git a/gcc/tree.c b/gcc/tree.c
index b661d3d..77a73b4 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);
}
}