[Bug rtl-optimization/67443] [5/6 regression] DSE removes required store instruction
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Oct 20 09:13:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67443
--- Comment #16 from Richard Biener <rguenth at gcc dot gnu.org> ---
I see multiple issues with ao_ref_from_mem connected with MEM_OFFSET/MEM_SIZE.
I don't remember exactly what was the issue with the promoted parameters
but it may have been with ranges_overlap_p not dealing with signed offsets
properly (that has been fixed meanwhile).
So I'd start with simply removing
/* If the base decl is a parameter we can have negative MEM_OFFSET in
case of promoted subregs on bigendian targets. Trust the MEM_EXPR
here. */
if (MEM_OFFSET (mem) < 0
&& (MEM_SIZE (mem) + MEM_OFFSET (mem)) * BITS_PER_UNIT == ref->size)
return true;
One issue that remains is that when MEM_OFFSET/MEM_SIZE gets us outside
of the MEM_EXPR object (its offset/size) we have to strip
handled-component-refs
until MEM_OFFSET/MEM_SIZE are again within bounds (or conservatively reset
ref->ref to NULL_TREE). Either the code adjusting the mem attributes
MEM_OFFSET/MEM_SIZE is supposed to do that already (no idea) or we'll run into
issues.
Basically MEM_SIZE must be <= ref->size, MEM_OFFSET may never be negative
unless ref->offset is zero and if MEM_OFFSET is positive then
MEM_OFFSET + MEM_SIZE must be <= ref->size.
It's of course a tricky area ;)
I believe that
/* If MEM_OFFSET and MEM_SIZE get us outside of the base object of
the MEM_EXPR punt. This happens for STRICT_ALIGNMENT targets a lot. */
if (MEM_EXPR (mem) != get_spill_slot_decl (false)
&& (ref->offset < 0
|| (DECL_P (ref->base)
&& (DECL_SIZE (ref->base) == NULL_TREE
|| TREE_CODE (DECL_SIZE (ref->base)) != INTEGER_CST
|| wi::ltu_p (wi::to_offset (DECL_SIZE (ref->base)),
ref->offset + ref->size)))))
return false;
will ultimatively "save" us here as well (very conservatively though).
So does
Index: gcc/alias.c
===================================================================
--- gcc/alias.c (revision 229022)
+++ gcc/alias.c (working copy)
@@ -339,15 +339,16 @@ ao_ref_from_mem (ao_ref *ref, const_rtx
|| !MEM_SIZE_KNOWN_P (mem))
return true;
- /* If the base decl is a parameter we can have negative MEM_OFFSET in
- case of promoted subregs on bigendian targets. Trust the MEM_EXPR
- here. */
+ /* If MEM_OFFSET/MEM_SIZE get us outside of ref->offset/ref->max_size
+ drop ref->ref. */
if (MEM_OFFSET (mem) < 0
- && (MEM_SIZE (mem) + MEM_OFFSET (mem)) * BITS_PER_UNIT == ref->size)
- return true;
+ || (ref->max_size != -1
+ && ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT
+ > ref->max_size)))
+ ref->ref = NULL_TREE;
- /* Otherwise continue and refine size and offset we got from analyzing
- MEM_EXPR by using MEM_SIZE and MEM_OFFSET. */
+ /* Refine size and offset we got from analyzing MEM_EXPR by using
+ MEM_SIZE and MEM_OFFSET. */
ref->offset += MEM_OFFSET (mem) * BITS_PER_UNIT;
ref->size = MEM_SIZE (mem) * BITS_PER_UNIT;
fix the issue?
More information about the Gcc-bugs
mailing list