diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/alias.c | 12 |
2 files changed, 17 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 634c4cc..47bef8c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2009-09-23 Richard Guenther <rguenther@suse.de> + * alias.c (ao_ref_from_mem): Correct for negative MEM_OFFSET + produced for bigendian targets with promoted subregs. + +2009-09-23 Richard Guenther <rguenther@suse.de> + * value-prof.c (gimple_ic): Purge old EH edges only after building the new ones. diff --git a/gcc/alias.c b/gcc/alias.c index eaa127e..6bb051e 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -309,6 +309,18 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem) ref->offset = 0; ref->max_size = -1; } + 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; + } else { ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT; |