tree-optimization/101088 - fix SM invalidation issue

Message ID nrss36qp-p38s-2p8p-070-6s56r9rr61p@fhfr.qr
State New
Headers show
Series
  • tree-optimization/101088 - fix SM invalidation issue
Related show

Commit Message

Richard Biener June 16, 2021, 10:15 a.m.
When we face a sm_ord vs sm_unord for the same ref during
store sequence merging we assert that the ref is already marked
unsupported.  But it can be that it will only be marked so
during the ongoing merging so instead of asserting mark it here.

Also apply some optimization to not waste resources to search
for already unsupported refs.

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

2021-06-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/101088
	* tree-ssa-loop-im.c (sm_seq_valid_bb): Only look for
	supported refs on edges.  Do not assert same ref but
	different kind stores are unsuported but mark them so.
	(hoist_memory_references): Only look for supported refs
	on exits.

	* gcc.dg/torture/pr101088.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr101088.c | 45 +++++++++++++++++++++++++
 gcc/tree-ssa-loop-im.c                  | 21 +++++++++---
 2 files changed, 61 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr101088.c

-- 
2.26.2

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr101088.c b/gcc/testsuite/gcc.dg/torture/pr101088.c
new file mode 100644
index 00000000000..00fce39d2f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr101088.c
@@ -0,0 +1,45 @@ 
+/* { dg-do compile } */
+
+int bh, on, h0;
+
+void
+qw (int n2)
+{
+  int *e5;
+
+  if (n2 == 0)
+    {
+      n2 = 1;
+      while (n2 != 0)
+	for (n2 = 0; n2 < 1; ++n2)
+	  {
+	  }
+
+      e5 = &n2;
+    }
+  else
+    e5 = &on;
+
+  while (h0 < 1)
+    {
+      if (on == 0)
+	{
+	  ++*e5;
+	  bh = 0;
+	}
+      else
+	{
+	  bh = 0;
+	  ++on;
+	  *e5 = on;
+	  h0 = *e5;
+	  if (h0 == 0)
+	    {
+	      *e5 = 0;
+	      ++h0;
+	    }
+	}
+
+      ++h0;
+    }
+}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 1c865b28fd6..7de47edbcb3 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -2340,7 +2340,13 @@  sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
 	      tree vuse = gimple_phi_arg_def (phi, i);
 	      edge e = gimple_phi_arg_edge (phi, i);
 	      auto_vec<seq_entry> edge_seq;
-	      bitmap_copy (tem_refs_not_in_seq, refs_not_in_seq);
+	      bitmap_and_compl (tem_refs_not_in_seq,
+				refs_not_in_seq, refs_not_supported);
+	      /* If we've marked all refs we search for as unsupported
+		 we can stop processing and use the sequence as before
+		 the PHI.  */
+	      if (bitmap_empty_p (tem_refs_not_in_seq))
+		return 1;
 	      eret = sm_seq_valid_bb (loop, e->src, vuse, edge_seq,
 				      tem_refs_not_in_seq, refs_not_supported,
 				      true, fully_visited);
@@ -2379,9 +2385,9 @@  sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
 		  /* sm_other prevails.  */
 		  else if (first_edge_seq[i].second != edge_seq[i].second)
 		    {
-		      /* This is just an optimization.  */
-		      gcc_assert (bitmap_bit_p (refs_not_supported,
-						first_edge_seq[i].first));
+		      /* Make sure the ref is marked as not supported.  */
+		      bitmap_set_bit (refs_not_supported,
+				      first_edge_seq[i].first);
 		      first_edge_seq[i].second = sm_other;
 		      first_edge_seq[i].from = NULL_TREE;
 		    }
@@ -2533,7 +2539,12 @@  hoist_memory_references (class loop *loop, bitmap mem_refs,
       vec<seq_entry> seq;
       seq.create (4);
       auto_bitmap refs_not_in_seq (&lim_bitmap_obstack);
-      bitmap_copy (refs_not_in_seq, mem_refs);
+      bitmap_and_compl (refs_not_in_seq, mem_refs, refs_not_supported);
+      if (bitmap_empty_p (refs_not_in_seq))
+	{
+	  seq.release ();
+	  break;
+	}
       auto_bitmap fully_visited;
       int res = sm_seq_valid_bb (loop, e->src, NULL_TREE,
 				 seq, refs_not_in_seq,