diff mbox series

tree-optimization/100053 - fix predication in VN

Message ID nycvar.YFH.7.76.2104131430380.32658@elmra.sevgm.obk
State New
Headers show
Series tree-optimization/100053 - fix predication in VN | expand

Commit Message

Richard Biener April 13, 2021, 12:30 p.m. UTC
This avoids doing optimistic dominance queries involving
non-executable backedges when validating recorded predicated values
in VN because we have no way to force re-evaluating validity when
optimistically not executable edges become executable later.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk.

2021-04-13  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/100053
	* tree-ssa-sccvn.c (vn_nary_op_get_predicated_value): Do
	not use optimistic dominance queries for backedges to validate
	predicated values.
	(dominated_by_p_w_unex): Add parameter to ignore executable
	state on backedges.
	(rpo_elim::eliminate_avail): Adjust.

	* gcc.dg/torture/pr100053.c: New testcase.
	* gcc.dg/tree-ssa/ssa-fre-93.c: Likewise.
---
 gcc/testsuite/gcc.dg/torture/pr100053.c    | 25 ++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c | 21 ++++++++++++++++++
 gcc/tree-ssa-sccvn.c                       | 21 +++++++++++-------
 3 files changed, 59 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr100053.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr100053.c b/gcc/testsuite/gcc.dg/torture/pr100053.c
new file mode 100644
index 00000000000..3d1767513f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr100053.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+
+int __attribute__((returns_twice,noipa)) x() { return 0; }
+void __attribute__((noipa)) ar() {}
+void __attribute__((noipa)) as() { __builtin_abort (); }
+int a1, a2, a3;
+void __attribute__((noipa)) v(int init)
+{
+  if (!init) {
+    as();
+    if (a1)
+      goto aq;
+    x ();
+  }
+  ar();
+aq:
+  if (!init)
+    as();
+}
+
+int main()
+{
+  v(1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c
new file mode 100644
index 00000000000..7f66b7ee3f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+void bar ();
+void foo (int pred, int *other)
+{
+  *other = 0;
+  if (*other)
+    goto cnt;
+  if (pred)
+    {
+      *other = 1;
+cnt:
+      if (!pred)
+        bar ();
+    }
+}
+
+/* The first VN pass should figure that if (!pred) is false because
+   if (*other) is and thus the predicate test is redundant.  */
+/* { dg-final { scan-tree-dump-not "bar" "fre1" } } */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 16e75b518b0..ca0974d72b8 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4171,7 +4171,7 @@  vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code,
 }
 
 static bool
-dominated_by_p_w_unex (basic_block bb1, basic_block bb2);
+dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool);
 
 static tree
 vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb)
@@ -4180,9 +4180,12 @@  vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb)
     return vno->u.result;
   for (vn_pval *val = vno->u.values; val; val = val->next)
     for (unsigned i = 0; i < val->n; ++i)
-      if (dominated_by_p_w_unex (bb,
-			  BASIC_BLOCK_FOR_FN
-			    (cfun, val->valid_dominated_by_p[i])))
+      /* Do not handle backedge executability optimistically since
+	 when figuring out whether to iterate we do not consider
+	 changed predication.  */
+      if (dominated_by_p_w_unex
+	    (bb, BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]),
+	     false))
 	return val->result;
   return NULL_TREE;
 }
@@ -4482,10 +4485,11 @@  vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
 
 
 /* Return true if BB1 is dominated by BB2 taking into account edges
-   that are not executable.  */
+   that are not executable.  When ALLOW_BACK is false consider not
+   executable backedges as executable.  */
 
 static bool
-dominated_by_p_w_unex (basic_block bb1, basic_block bb2)
+dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back)
 {
   edge_iterator ei;
   edge e;
@@ -4502,7 +4506,8 @@  dominated_by_p_w_unex (basic_block bb1, basic_block bb2)
     {
       edge prede = NULL;
       FOR_EACH_EDGE (e, ei, bb1->preds)
-	if (e->flags & EDGE_EXECUTABLE)
+	if ((e->flags & EDGE_EXECUTABLE)
+	    || (!allow_back && (e->flags & EDGE_DFS_BACK)))
 	  {
 	    if (prede)
 	      {
@@ -6901,7 +6906,7 @@  rpo_elim::eliminate_avail (basic_block bb, tree op)
 	     may also be able to "pre-compute" (bits of) the next immediate
 	     (non-)dominator during the RPO walk when marking edges as
 	     executable.  */
-	  if (dominated_by_p_w_unex (bb, abb))
+	  if (dominated_by_p_w_unex (bb, abb, true))
 	    {
 	      tree leader = ssa_name (av->leader);
 	      /* Prevent eliminations that break loop-closed SSA.  */