From 0424a5ece5307cc22bbc0fe97edf4707d7a798ed Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 5 May 2020 11:00:09 +0200 Subject: [PATCH] tree-optimization/94949 - fix load eliding in SM This fixes the case of not using the multithreaded model when only conditionally storing to the destination. We cannot elide the load in this case. 2020-05-05 Richard Biener PR tree-optimization/94949 * tree-ssa-loop-im.c (execute_sm): Check whether we use the multithreaded model or always compute the stored value before eliding a load. * gcc.dg/torture/pr94949.c: New testcase. --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr94949.c | 17 +++++++++++++++++ gcc/tree-ssa-loop-im.c | 10 ++++++---- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr94949.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a419757bf8..2267a63bca1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-05-05 Richard Biener + + PR tree-optimization/94949 + * tree-ssa-loop-im.c (execute_sm): Check whether we use + the multithreaded model or always compute the stored value + before eliding a load. + 2020-05-05 Alex Coplan * config/aarch64/aarch64.md (*one_cmpl_zero_extend): New. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e06bcf86212..2ffa0f8f434 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-05-05 Richard Biener + + PR tree-optimization/94949 + * gcc.dg/torture/pr94949.c: New testcase. + 2020-05-05 Alex Coplan * gcc.target/aarch64/mvn_zero_ext.c: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr94949.c b/gcc/testsuite/gcc.dg/torture/pr94949.c new file mode 100644 index 00000000000..6182d77b3cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr94949.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fallow-store-data-races" } */ + +static int x = 1; +static volatile int y = -1; +int +main() +{ + for (int i = 0; i < 128; ++i) + { + if (i == y) + x = i; + } + if (x != 1) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 18e5c18c17e..554dd4be5bb 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -2128,9 +2128,9 @@ execute_sm (class loop *loop, vec exits, im_mem_ref *ref) fmt_data.orig_loop = loop; for_each_index (&ref->mem.ref, force_move_till, &fmt_data); + bool always_stored = ref_always_accessed_p (loop, ref, true); if (bb_in_transaction (loop_preheader_edge (loop)->src) - || (! flag_store_data_races - && ! ref_always_accessed_p (loop, ref, true))) + || (! flag_store_data_races && ! always_stored)) multi_threaded_model_p = true; if (multi_threaded_model_p) @@ -2145,8 +2145,10 @@ execute_sm (class loop *loop, vec exits, im_mem_ref *ref) /* Avoid doing a load if there was no load of the ref in the loop. Esp. when the ref is not always stored we cannot optimize it - away later. */ - if (ref->loaded && bitmap_bit_p (ref->loaded, loop->num)) + away later. But when it is not always stored we must use a conditional + store then. */ + if ((!always_stored && !multi_threaded_model_p) + || (ref->loaded && bitmap_bit_p (ref->loaded, loop->num))) { load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref)); lim_data = init_lim_data (load); -- 2.30.2