Since we apply SM to an edge which exits multiple loops we have
to make sure to commit insertions on it immediately since otherwise
store order is not preserved.

The testcase was committed with yesterdays fix, the bug was still
latent (with careful -fdbgcnt=lim you could still trigger it).

Bootstrapped / tested on x86_64-unknown-linux-gnu, applied.

Richard.

2020-05-11  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/95045
        * dbgcnt.def (lim): Add debug-counter.
        * tree-ssa-loop-im.c: Include dbgcnt.h.
        (find_refs_for_sm): Use lim debug counter for store motion
        candidates.
        (do_store_motion): Rename form store_motion.  Commit edge
        insertions...
        (store_motion_loop): ... here.
        (tree_ssa_lim): Adjust.
---
 gcc/dbgcnt.def         |  1 +
 gcc/tree-ssa-loop-im.c | 15 ++++++++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index 232b1928983..3998c9636aa 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -174,6 +174,7 @@ DEBUG_COUNTER (ipa_sra_params)
 DEBUG_COUNTER (ipa_sra_retvalues)
 DEBUG_COUNTER (ira_move)
 DEBUG_COUNTER (ivopts_loop)
+DEBUG_COUNTER (lim)
 DEBUG_COUNTER (local_alloc_for_sched)
 DEBUG_COUNTER (match)
 DEBUG_COUNTER (merged_ipa_icf)
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index bb78dfb2ce8..0d77aaa08a5 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 #include "builtins.h"
 #include "tree-dfa.h"
+#include "dbgcnt.h"
 
 /* TODO:  Support for predicated code motion.  I.e.
 
@@ -2862,7 +2863,7 @@ find_refs_for_sm (class loop *loop, bitmap sm_executed, 
bitmap refs_to_sm)
   EXECUTE_IF_AND_COMPL_IN_BITMAP (refs, sm_executed, 0, i, bi)
     {
       ref = memory_accesses.refs_list[i];
-      if (can_sm_ref_p (loop, ref))
+      if (can_sm_ref_p (loop, ref) && dbg_cnt (lim))
        bitmap_set_bit (refs_to_sm, i);
     }
 }
@@ -2900,7 +2901,12 @@ store_motion_loop (class loop *loop, bitmap sm_executed)
     {
       find_refs_for_sm (loop, sm_executed, sm_in_loop);
       if (!bitmap_empty_p (sm_in_loop))
-       hoist_memory_references (loop, sm_in_loop, exits);
+       {
+         hoist_memory_references (loop, sm_in_loop, exits);
+         /* Commit edge inserts here to preserve the order of stores
+            when an exit exits multiple loops.  */
+         gsi_commit_edge_inserts ();
+       }
     }
   exits.release ();
 
@@ -2915,7 +2921,7 @@ store_motion_loop (class loop *loop, bitmap sm_executed)
    loops.  */
 
 static void
-store_motion (void)
+do_store_motion (void)
 {
   class loop *loop;
   bitmap sm_executed = BITMAP_ALLOC (&lim_bitmap_obstack);
@@ -2924,7 +2930,6 @@ store_motion (void)
     store_motion_loop (loop, sm_executed);
 
   BITMAP_FREE (sm_executed);
-  gsi_commit_edge_inserts ();
 }
 
 /* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
@@ -3141,7 +3146,7 @@ tree_ssa_lim (void)
 
   /* Execute store motion.  Force the necessary invariants to be moved
      out of the loops as well.  */
-  store_motion ();
+  do_store_motion ();
 
   /* Move the expressions that are expensive enough.  */
   todo = move_computations ();
-- 
2.25.1

Reply via email to