This makes ao_ref_from_mem less conservative if either MEM_OFFSET or MEM_SIZE is not set. From other alias.c code and set_mem_attributes_minus_bitpos one has to conclude that MEM_EXPR is always conservatively correct (it only can cover a larger memory area) and the MEM_OFFSET / MEM_SIZE pair can refine it. Thus, we can make ao_ref_from_mem less conservative when, for example, faced with variable array accesses which set_mem_attributes_minus_bitpos ends up representing with an unknown MEM_OFFSET.
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2012-06-11 Richard Guenther <rguent...@suse.de> * emit-rtl.c (set_mem_attributes_minus_bitpos): Remove dead code. * alias.c (ao_ref_from_mem): MEM_EXPR is conservative, MEM_OFFSET and MEM_SIZE only refines it. Reflect that and be less conservative if either of the latter is not known. Index: gcc/emit-rtl.c =================================================================== *** gcc/emit-rtl.c (revision 188384) --- gcc/emit-rtl.c (working copy) *************** set_mem_attributes_minus_bitpos (rtx ref *** 1838,1852 **** /* ??? Any reason the field size would be different than the size we got from the type? */ } - - /* If this is an indirect reference, record it. */ - else if (TREE_CODE (t) == MEM_REF) - { - attrs.expr = t; - attrs.offset_known_p = true; - attrs.offset = 0; - apply_bitpos = bitpos; - } } /* If this is an indirect reference, record it. */ --- 1838,1843 ---- Index: gcc/alias.c =================================================================== *** gcc/alias.c (revision 188384) --- gcc/alias.c (working copy) *************** ao_ref_from_mem (ao_ref *ref, const_rtx *** 326,342 **** ref->ref_alias_set = MEM_ALIAS_SET (mem); ! /* If MEM_OFFSET or MEM_SIZE are unknown we have to punt. ! Keep points-to related information though. */ if (!MEM_OFFSET_KNOWN_P (mem) || !MEM_SIZE_KNOWN_P (mem)) ! { ! ref->ref = NULL_TREE; ! ref->offset = 0; ! ref->size = -1; ! ref->max_size = -1; ! 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 --- 326,336 ---- ref->ref_alias_set = MEM_ALIAS_SET (mem); ! /* If MEM_OFFSET or MEM_SIZE are unknown what we got from MEM_EXPR ! is conservative, so trust it. */ if (!MEM_OFFSET_KNOWN_P (mem) || !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 *************** ao_ref_from_mem (ao_ref *ref, const_rtx *** 345,350 **** --- 339,347 ---- && (MEM_SIZE (mem) + MEM_OFFSET (mem)) * BITS_PER_UNIT == ref->size) return true; + /* Otherwise continue and 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;