[PATCH] tree-optimization/101025 - fix store-motion dependence checking

Richard Biener rguenther@suse.de
Fri Jun 11 13:53:22 GMT 2021


This plugs a hole in store-motion where it fails to perform dependence
checking on conditionally executed but not store-motioned refs.

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

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

	PR tree-optimization/101025
	* tree-ssa-loop-im.c (sm_seq_valid_bb): Make sure to process
	all refs that require dependence checking.

	* gcc.dg/torture/pr101025.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr101025.c | 23 +++++++++++++++
 gcc/tree-ssa-loop-im.c                  | 38 +++++++++++++++++++++++--
 2 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr101025.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr101025.c b/gcc/testsuite/gcc.dg/torture/pr101025.c
new file mode 100644
index 00000000000..483e0ff7997
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr101025.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+int a[10];
+int b, d, g;
+volatile char c;
+short e;
+volatile int f;
+int main()
+{
+  for (; d <= 9; d++) {
+      b = e = 0;
+      for (; e < 4; e++)
+        a[e] = 4;
+      for (; b <= 3; b++)
+        if (g)
+          f = 0;
+        else
+          a[b] = c;
+  }
+  if (a[1] != 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 8034cf68d27..1c865b28fd6 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -2169,6 +2169,7 @@ execute_sm (class loop *loop, im_mem_ref *ref,
 enum sm_kind { sm_ord, sm_unord, sm_other };
 struct seq_entry
 {
+  seq_entry () {}
   seq_entry (unsigned f, sm_kind k, tree fr = NULL)
     : first (f), second (k), from (fr) {}
   unsigned first;
@@ -2352,6 +2353,8 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
 	      unsigned min_len = MIN(first_edge_seq.length (),
 				     edge_seq.length ());
 	      /* Incrementally merge seqs into first_edge_seq.  */
+	      int first_uneq = -1;
+	      auto_vec<seq_entry, 2> extra_refs;
 	      for (unsigned int i = 0; i < min_len; ++i)
 		{
 		  /* ???  We can more intelligently merge when we face different
@@ -2367,6 +2370,11 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
 			bitmap_set_bit (refs_not_supported, edge_seq[i].first);
 		      first_edge_seq[i].second = sm_other;
 		      first_edge_seq[i].from = NULL_TREE;
+		      /* Record the dropped refs for later processing.  */
+		      if (first_uneq == -1)
+			first_uneq = i;
+		      extra_refs.safe_push (seq_entry (edge_seq[i].first,
+						       sm_other, NULL_TREE));
 		    }
 		  /* sm_other prevails.  */
 		  else if (first_edge_seq[i].second != edge_seq[i].second)
@@ -2399,10 +2407,36 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
 		}
 	      else if (edge_seq.length () > first_edge_seq.length ())
 		{
+		  if (first_uneq == -1)
+		    first_uneq = first_edge_seq.length ();
 		  for (unsigned i = first_edge_seq.length ();
 		       i < edge_seq.length (); ++i)
-		    if (edge_seq[i].second == sm_ord)
-		      bitmap_set_bit (refs_not_supported, edge_seq[i].first);
+		    {
+		      if (edge_seq[i].second == sm_ord)
+			bitmap_set_bit (refs_not_supported, edge_seq[i].first);
+		      extra_refs.safe_push (seq_entry (edge_seq[i].first,
+						       sm_other, NULL_TREE));
+		    }
+		}
+	      /* Put unmerged refs at first_uneq to force dependence checking
+		 on them.  */
+	      if (first_uneq != -1)
+		{
+		  /* Missing ordered_splice_at.  */
+		  if ((unsigned)first_uneq == first_edge_seq.length ())
+		    first_edge_seq.safe_splice (extra_refs);
+		  else
+		    {
+		      unsigned fes_length = first_edge_seq.length ();
+		      first_edge_seq.safe_grow (fes_length
+						+ extra_refs.length ());
+		      memmove (&first_edge_seq[first_uneq + extra_refs.length ()],
+			       &first_edge_seq[first_uneq],
+			       (fes_length - first_uneq) * sizeof (seq_entry));
+		      memcpy (&first_edge_seq[first_uneq],
+			      extra_refs.address (),
+			      extra_refs.length () * sizeof (seq_entry));
+		    }
 		}
 	    }
 	  /* Use the sequence from the first edge and push SMs down.  */
-- 
2.26.2


More information about the Gcc-patches mailing list