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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |ebotcazou at gcc dot gnu.org
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, so it's not scheduling but RTL DSE removing the dynamic type changing
store:

**scanning insn=16
mems_found = 0, cannot_delete = false
Locally deleting insn 9 because insn 8 stores the same value and couldn't be
eliminated
Locally deleting insn 9

this is exactly the "feature" we had to guard properly on the GIMPLE level.
Later it isn't CSE that messes up things (like on GIMPLE) but the new
sequence is of course prone to scheduling.

But instead of not doing the dead store removal like on GIMPLE we can
choose to adjust the earlier store accordingly (we don't get a hold on
that easily on GIMPLE, but it seems to be available in DSE).

So the following fixes the testcase, still removes the redundant store
but possibly pessimizes followup TBAA because alias-set zero is the
safe and pessimistic choice.  I guess the alias sets will usually match
though.  Testing this now - hopefully the data structures reference the
correct stores and are always populated like I access them ;)

Index: gcc/dse.c
===================================================================
--- gcc/dse.c   (revision 257043)
+++ gcc/dse.c   (working copy)
@@ -2725,6 +2725,14 @@ dse_step1 (void)
                                            "eliminated\n",
                                 INSN_UID (ptr->insn),
                                 INSN_UID (s_info->redundant_reason->insn));
+                     /* If the later store we delete could have changed the
+                        dynamic type of the memory make sure the one we
+                        preserve serves as a store for all loads that could
+                        validly have accessed the one we delete.  */
+                     store_info *r_info = s_info->redundant_reason->store_rec;
+                     if (MEM_ALIAS_SET (s_info->mem)
+                         != MEM_ALIAS_SET (r_info->mem))
+                       set_mem_alias_set (r_info->mem, 0);
                      delete_dead_store_insn (ptr);
                    }
                  free_store_info (ptr);

Reply via email to