diff mbox series

tree-optimization/105484 - VEC_SET and EH

Message ID 20220505083052.2E27213B11@imap2.suse-dmz.suse.de
State New
Headers show
Series tree-optimization/105484 - VEC_SET and EH | expand

Commit Message

Richard Biener May 5, 2022, 8:30 a.m. UTC
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.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

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.
---
 gcc/gimple-isel.cc                      | 19 ++++++++++++-------
 gcc/testsuite/gcc.dg/torture/pr105484.c | 15 +++++++++++++++
 2 files changed, 27 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr105484.c
diff mbox series

Patch

diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index a8f7a0d25d0..4b309a05a9a 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 00000000000..f2a5eb8a7ee
--- /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]);
+}