[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