aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-05-05 09:34:59 +0200
committerRichard Biener <rguenther@suse.de>2022-05-05 10:36:49 +0200
commite1a41143a2e24c65d94364fd82b165ff71a759d8 (patch)
treecc4e56a30092275b6d77f7b127b918cab01176fd /gcc
parent938a02a589dc22cef65bba2b131fc9e4874baddb (diff)
downloadgcc-e1a41143a2e24c65d94364fd82b165ff71a759d8.zip
gcc-e1a41143a2e24c65d94364fd82b165ff71a759d8.tar.gz
gcc-e1a41143a2e24c65d94364fd82b165ff71a759d8.tar.bz2
tree-optimization/105484 - VEC_SET and EH
When the IL representation of VEC_SET is marked as throwing (unnecessarily), we need to clean that when replacing it with the .VEC_SET internal function call which cannot throw. 2022-05-05 Richard Biener <rguenther@suse.de> PR tree-optimization/105484 * gimple-isel.cc (gimple_expand_vec_set_expr): Clean EH, return whether the CFG changed. (gimple_expand_vec_exprs): When the CFG changed, clean it up. * gcc.dg/torture/pr105484.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-isel.cc19
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr105484.c15
2 files changed, 27 insertions, 7 deletions
diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index a8f7a0d..4b309a0 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -49,22 +49,23 @@ along with GCC; see the file COPYING3. If not see
_8 = .VEC_SET (_7, i_4(D), _1);
u = _8; */
-static gimple *
+static bool
gimple_expand_vec_set_expr (struct function *fun, gimple_stmt_iterator *gsi)
{
enum tree_code code;
gcall *new_stmt = NULL;
gassign *ass_stmt = NULL;
+ bool cfg_changed = false;
/* Only consider code == GIMPLE_ASSIGN. */
gassign *stmt = dyn_cast<gassign *> (gsi_stmt (*gsi));
if (!stmt)
- return NULL;
+ return false;
tree lhs = gimple_assign_lhs (stmt);
code = TREE_CODE (lhs);
if (code != ARRAY_REF)
- return NULL;
+ return false;
tree val = gimple_assign_rhs1 (stmt);
tree op0 = TREE_OPERAND (lhs, 0);
@@ -98,12 +99,15 @@ gimple_expand_vec_set_expr (struct function *fun, gimple_stmt_iterator *gsi)
gimple_set_location (ass_stmt, loc);
gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT);
+ basic_block bb = gimple_bb (stmt);
gimple_move_vops (ass_stmt, stmt);
- gsi_remove (gsi, true);
+ if (gsi_remove (gsi, true)
+ && gimple_purge_dead_eh_edges (bb))
+ cfg_changed = true;
}
}
- return ass_stmt;
+ return cfg_changed;
}
/* Expand all VEC_COND_EXPR gimple assignments into calls to internal
@@ -297,6 +301,7 @@ gimple_expand_vec_exprs (struct function *fun)
basic_block bb;
hash_map<tree, unsigned int> vec_cond_ssa_name_uses;
auto_bitmap dce_ssa_names;
+ bool cfg_changed = false;
FOR_EACH_BB_FN (bb, fun)
{
@@ -311,7 +316,7 @@ gimple_expand_vec_exprs (struct function *fun)
gsi_replace (&gsi, g, false);
}
- gimple_expand_vec_set_expr (fun, &gsi);
+ cfg_changed |= gimple_expand_vec_set_expr (fun, &gsi);
if (gsi_end_p (gsi))
break;
}
@@ -323,7 +328,7 @@ gimple_expand_vec_exprs (struct function *fun)
simple_dce_from_worklist (dce_ssa_names);
- return 0;
+ return cfg_changed ? TODO_cleanup_cfg : 0;
}
namespace {
diff --git a/gcc/testsuite/gcc.dg/torture/pr105484.c b/gcc/testsuite/gcc.dg/torture/pr105484.c
new file mode 100644
index 0000000..f2a5eb8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr105484.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fnon-call-exceptions -fno-tree-dce -fno-tree-forwprop" } */
+/* { dg-additional-options "-march=cannonlake" { target x86_64-*-* i?86-*-* } } */
+
+typedef int __attribute__((__vector_size__ (16))) V;
+
+void bar (int i);
+
+void
+foo (int i)
+{
+ V v;
+ __builtin_mul_overflow (7, i, &v[i]);
+ bar ((V){}[3]);
+}