https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92038

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Just a proof of concept:
--- gcc/gimple-ssa-store-merging.c.jj   2019-10-02 16:35:21.016450769 +0200
+++ gcc/gimple-ssa-store-merging.c      2019-10-10 11:51:20.912101959 +0200
@@ -4361,7 +4361,6 @@ rhs_valid_for_store_merging_p (tree rhs)
 {
   unsigned HOST_WIDE_INT size;
   if (TREE_CODE (rhs) == CONSTRUCTOR
-      && !TREE_CLOBBER_P (rhs)
       && CONSTRUCTOR_NELTS (rhs) == 0
       && TYPE_SIZE_UNIT (TREE_TYPE (rhs))
       && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (rhs))))
@@ -4794,7 +4793,7 @@ store_valid_for_store_merging_p (gimple
   return gimple_assign_single_p (stmt)
         && gimple_vdef (stmt)
         && lhs_valid_for_store_merging_p (gimple_assign_lhs (stmt))
-        && !gimple_has_volatile_ops (stmt);
+        && (!gimple_has_volatile_ops (stmt) || gimple_clobber_p (stmt));
 }

 enum basic_block_status { BB_INVALID, BB_VALID, BB_EXTENDED_VALID };
@@ -4875,7 +4874,7 @@ pass_store_merging::execute (function *f
          if (is_gimple_debug (stmt))
            continue;

-         if (gimple_has_volatile_ops (stmt))
+         if (gimple_has_volatile_ops (stmt) && !gimple_clobber_p (stmt))
            {
              /* Terminate all chains.  */
              if (dump_file && (dump_flags & TDF_DETAILS))
fixes the #c5 testcase, but breaks the #c0 one, so this shows we need to handle
clobbers
more carefully.  The reason #c0 breaks is that the rest of store-merging
considers the = {}
stores as zeroing and so thinks if it leaves it in the stream, it will zero it.
 That is not the case with the clobbers.
I guess we also need to be careful when clobbers happen in the middle of store
sequence rather than just at the start
(the question is if it wouldn't be better if some earlier pass (DSE) removed in
  MEM[(struct  &)&D.16119] ={v} {CLOBBER};
  MEM[(struct _Uninitialized *)&D.16119] ={v} {CLOBBER};
The first one is a 5 byte clobber, the second one 4 byte clobber and when the
second one must alias the first one and is a subset of the previous one, I
don't see an advantage in keeping both).
If say DSE removes that, we could just punt on a clobber in the middle and
handle carefully clobber at the start (make sure to keep the clobber unless we
perhaps overwrite it fully, and don't count the clobber as another stmt unless
we manage to overwrite it fully).

Reply via email to