alias.c (ao_ref_from_mem): Properly deal with off decl accesses resulting from stack temporaries on...
2009-09-29 Richard Guenther <rguenther@suse.de> * alias.c (ao_ref_from_mem): Properly deal with off decl accesses resulting from stack temporaries on STRICT_ALIGNMENT targets. From-SVN: r152278
This commit is contained in:
parent
4b653ed5a4
commit
b0e96404c1
@ -1,3 +1,8 @@
|
|||||||
|
2009-09-29 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
* alias.c (ao_ref_from_mem): Properly deal with off decl accesses
|
||||||
|
resulting from stack temporaries on STRICT_ALIGNMENT targets.
|
||||||
|
|
||||||
2009-09-29 Nick Clifton <nickc@redhat.com>
|
2009-09-29 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* function.c (current_function_name): If there is no current
|
* function.c (current_function_name): If there is no current
|
||||||
|
64
gcc/alias.c
64
gcc/alias.c
@ -265,6 +265,11 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
|
|||||||
if (!expr)
|
if (!expr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/* If MEM_OFFSET or MEM_SIZE are NULL punt. */
|
||||||
|
if (!MEM_OFFSET (mem)
|
||||||
|
|| !MEM_SIZE (mem))
|
||||||
|
return false;
|
||||||
|
|
||||||
ao_ref_init (ref, expr);
|
ao_ref_init (ref, expr);
|
||||||
|
|
||||||
/* Get the base of the reference and see if we have to reject or
|
/* Get the base of the reference and see if we have to reject or
|
||||||
@ -302,45 +307,32 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
|
|||||||
|
|
||||||
ref->ref_alias_set = MEM_ALIAS_SET (mem);
|
ref->ref_alias_set = MEM_ALIAS_SET (mem);
|
||||||
|
|
||||||
/* For NULL MEM_OFFSET the MEM_EXPR may have been stripped arbitrarily
|
/* If the base decl is a parameter we can have negative MEM_OFFSET in
|
||||||
without recording offset or extent adjustments properly. */
|
case of promoted subregs on bigendian targets. Trust the MEM_EXPR
|
||||||
if (MEM_OFFSET (mem) == NULL_RTX)
|
here. */
|
||||||
{
|
if (INTVAL (MEM_OFFSET (mem)) < 0
|
||||||
ref->offset = 0;
|
&& ((INTVAL (MEM_SIZE (mem)) + INTVAL (MEM_OFFSET (mem)))
|
||||||
ref->max_size = -1;
|
* BITS_PER_UNIT) == ref->size)
|
||||||
}
|
|
||||||
else if (INTVAL (MEM_OFFSET (mem)) < 0
|
|
||||||
&& MEM_EXPR (mem) != get_spill_slot_decl (false))
|
|
||||||
{
|
|
||||||
/* Negative MEM_OFFSET happens for promoted subregs on bigendian
|
|
||||||
targets. We need to compensate both the size and the offset here,
|
|
||||||
which get_ref_base_and_extent will have done based on the MEM_EXPR
|
|
||||||
already. */
|
|
||||||
gcc_assert (((INTVAL (MEM_SIZE (mem)) + INTVAL (MEM_OFFSET (mem)))
|
|
||||||
* BITS_PER_UNIT)
|
|
||||||
== ref->size);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NULL MEM_SIZE should not really happen with a non-NULL MEM_EXPR,
|
ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT;
|
||||||
but just play safe here. The size may have been adjusted together
|
|
||||||
with the offset, so we need to take it if it is set and not rely
|
|
||||||
on MEM_EXPR here (which has the size determining parts potentially
|
|
||||||
stripped anyway). We lose precision for max_size which is only
|
|
||||||
available from the remaining MEM_EXPR. */
|
|
||||||
if (MEM_SIZE (mem) == NULL_RTX)
|
|
||||||
{
|
|
||||||
ref->size = -1;
|
|
||||||
ref->max_size = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ref->size = INTVAL (MEM_SIZE (mem)) * BITS_PER_UNIT;
|
ref->size = INTVAL (MEM_SIZE (mem)) * BITS_PER_UNIT;
|
||||||
}
|
|
||||||
|
/* The MEM may extend into adjacent fields, so adjust max_size if
|
||||||
|
necessary. */
|
||||||
|
if (ref->max_size != -1
|
||||||
|
&& ref->size > ref->max_size)
|
||||||
|
ref->max_size = ref->size;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
&& (!host_integerp (DECL_SIZE (ref->base), 1)
|
||||||
|
|| (TREE_INT_CST_LOW (DECL_SIZE ((ref->base)))
|
||||||
|
< (unsigned HOST_WIDE_INT)(ref->offset + ref->size))))))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user