aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-06-22 14:59:09 +0200
committerRichard Biener <rguenther@suse.de>2024-06-23 11:23:48 +0200
commit8a1795bddcd34284936af4706f762d89c60fc69c (patch)
tree6e00577b6d1bf27c58643ca03466859c657c5c92
parent4c957d7ba84d8bbce6e778048f38e92ef71806c8 (diff)
downloadgcc-8a1795bddcd34284936af4706f762d89c60fc69c.zip
gcc-8a1795bddcd34284936af4706f762d89c60fc69c.tar.gz
gcc-8a1795bddcd34284936af4706f762d89c60fc69c.tar.bz2
tree-optimization/115579 - fix wrong code with store-motion
The recent change to relax store motion for variables that cannot have store data races broke the optimization to share flag vars for stores that all happen in the same single BB. The following fixes this. PR tree-optimization/115579 * tree-ssa-loop-im.cc (execute_sm): Return the auxiliary data created. (hoist_memory_references): Record the flag var that's eventually created and re-use it when all stores are in the same BB. * gcc.dg/pr115579.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/pr115579.c18
-rw-r--r--gcc/tree-ssa-loop-im.cc27
2 files changed, 32 insertions, 13 deletions
diff --git a/gcc/testsuite/gcc.dg/pr115579.c b/gcc/testsuite/gcc.dg/pr115579.c
new file mode 100644
index 0000000..0478105
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr115579.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-Os -fno-tree-sra" } */
+
+int printf(const char *, ...);
+int a, b = 1, c;
+int main() {
+ int d[2], *e = &d[1];
+ while (a) {
+ int *f = &b;
+ d[1] = 0;
+ *f = 0;
+ }
+ if (c)
+ printf("%d\n", *e);
+ if (b != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 3acbd88..61c6339 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -2269,7 +2269,7 @@ struct sm_aux
temporary variable is put to the preheader of the loop, and assignments
to the reference from the temporary variable are emitted to exits. */
-static void
+static sm_aux *
execute_sm (class loop *loop, im_mem_ref *ref,
hash_map<im_mem_ref *, sm_aux *> &aux_map, bool maybe_mt,
bool use_other_flag_var)
@@ -2345,6 +2345,8 @@ execute_sm (class loop *loop, im_mem_ref *ref,
lim_data->tgt_loop = loop;
gsi_insert_before (&gsi, load, GSI_SAME_STMT);
}
+
+ return aux;
}
/* sm_ord is used for ordinary stores we can retain order with respect
@@ -2802,20 +2804,18 @@ hoist_memory_references (class loop *loop, bitmap mem_refs,
hash_map<im_mem_ref *, sm_aux *> aux_map;
/* Execute SM but delay the store materialization for ordered
- sequences on exit. */
- bool first_p = true;
+ sequences on exit. Remember a created flag var and make
+ sure to re-use it. */
+ sm_aux *flag_var_aux = nullptr;
EXECUTE_IF_SET_IN_BITMAP (mem_refs, 0, i, bi)
{
ref = memory_accesses.refs_list[i];
- execute_sm (loop, ref, aux_map, true, !first_p);
- first_p = false;
+ sm_aux *aux = execute_sm (loop, ref, aux_map, true,
+ flag_var_aux != nullptr);
+ if (aux->store_flag)
+ flag_var_aux = aux;
}
- /* Get at the single flag variable we eventually produced. */
- im_mem_ref *ref
- = memory_accesses.refs_list[bitmap_first_set_bit (mem_refs)];
- sm_aux *aux = *aux_map.get (ref);
-
/* Materialize ordered store sequences on exits. */
edge e;
FOR_EACH_VEC_ELT (exits, i, e)
@@ -2826,13 +2826,14 @@ hoist_memory_references (class loop *loop, bitmap mem_refs,
/* Construct the single flag variable control flow and insert
the ordered seq of stores in the then block. With
-fstore-data-races we can do the stores unconditionally. */
- if (aux->store_flag)
+ if (flag_var_aux)
insert_e
= single_pred_edge
(execute_sm_if_changed (e, NULL_TREE, NULL_TREE,
- aux->store_flag,
+ flag_var_aux->store_flag,
loop_preheader_edge (loop),
- &aux->flag_bbs, append_cond_position,
+ &flag_var_aux->flag_bbs,
+ append_cond_position,
last_cond_fallthru));
execute_sm_exit (loop, insert_e, seq, aux_map, sm_ord,
append_cond_position, last_cond_fallthru);