tree-optimization/94949 - fix load eliding in SM
authorRichard Biener <rguenther@suse.de>
Tue, 5 May 2020 09:00:09 +0000 (11:00 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 5 May 2020 10:35:05 +0000 (12:35 +0200)
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  <rguenther@suse.de>

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
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr94949.c [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

index 6a419757bf897f8ecaf3930062ca5d80b1c6aa41..2267a63bca13e7821ee2172bf1d019a04c5db21c 100644 (file)
@@ -1,3 +1,10 @@
+2020-05-05  Richard Biener  <rguenther@suse.de>
+
+       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  <alex.coplan@arm.com>
 
        * config/aarch64/aarch64.md (*one_cmpl_zero_extend): New.
index e06bcf862123acda2bebcee804422aa22bc25050..2ffa0f8f43416fcc429c7babe41f3246b5c146df 100644 (file)
@@ -1,3 +1,8 @@
+2020-05-05  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/94949
+       * gcc.dg/torture/pr94949.c: New testcase.
+
 2020-05-05  Alex Coplan  <alex.coplan@arm.com>
 
        * 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 (file)
index 0000000..6182d77
--- /dev/null
@@ -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;
+}
index 18e5c18c17eb7472e96a9252d60b5a50698f8f1a..554dd4be5bbcfb1496c8111e5cce1d61e23d98ab 100644 (file)
@@ -2128,9 +2128,9 @@ execute_sm (class loop *loop, vec<edge> 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<edge> 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);