From: Richard Biener Date: Fri, 11 Jun 2021 10:06:08 +0000 (+0200) Subject: tree-optimization/101025 - fix store-motion dependence checking X-Git-Tag: upstream/12.2.0~7305 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b8b80b8aa3d9a7abbcb59b651ea5e84c2ea12d0b;p=platform%2Fupstream%2Fgcc.git tree-optimization/101025 - fix store-motion dependence checking This plugs a hole in store-motion where it fails to perform dependence checking on conditionally executed but not store-motioned refs. 2021-06-11 Richard Biener 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. --- diff --git a/gcc/testsuite/gcc.dg/torture/pr101025.c b/gcc/testsuite/gcc.dg/torture/pr101025.c new file mode 100644 index 0000000..483e0ff --- /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 8034cf6..1c865b2 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 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. */