summaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-11 15:48:40 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-11 15:48:40 +0000
commit47d3d2304f73cd8895687dbd19d44415bfc3a26b (patch)
tree4f082545fd981f2ad5cda9e4d3a2d1b8db212f39 /gcc/alias.c
parent04e1504c3c0281534d2e821f8b47ae5bc514acc8 (diff)
downloadgcc-47d3d2304f73cd8895687dbd19d44415bfc3a26b.tar.gz
PR middle-end/68999
* alias.c (base_alias_check): Move check for addresses with alignment ANDs before the call for compare_base_decls. (memrefs_conflict_p): Return -1 for different decls that went through alignment adjustments. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232229 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 1b8390e85bb..ccfad4d8386 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -2093,17 +2093,6 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
if (rtx_equal_p (x_base, y_base))
return 1;
- if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
- {
- tree x_decl = SYMBOL_REF_DECL (x_base);
- tree y_decl = SYMBOL_REF_DECL (y_base);
-
- /* We can assume that no stores are made to labels. */
- if (!x_decl || !y_decl)
- return 0;
- return compare_base_decls (x_decl, y_decl) != 0;
- }
-
/* The base addresses are different expressions. If they are not accessed
via AND, there is no conflict. We can bring knowledge of object
alignment into play here. For example, on alpha, "char a, b;" can
@@ -2122,6 +2111,17 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
|| (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
return 1;
+ if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
+ {
+ tree x_decl = SYMBOL_REF_DECL (x_base);
+ tree y_decl = SYMBOL_REF_DECL (y_base);
+
+ /* We can assume that no stores are made to labels. */
+ if (!x_decl || !y_decl)
+ return 0;
+ return compare_base_decls (x_decl, y_decl) != 0;
+ }
+
/* Differing symbols not accessed via AND never alias. */
if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
return 0;
@@ -2344,6 +2344,12 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
/* If both decls are the same, decide by offsets. */
if (cmp == 1)
return offset_overlap_p (c, xsize, ysize);
+ /* Assume a potential overlap for symbolic addresses that went
+ through alignment adjustments (i.e., that have negative
+ sizes), because we can't know how far they are from each
+ other. */
+ if (xsize < 0 || ysize < 0)
+ return -1;
/* If decls are different or we know by offsets that there is no overlap,
we win. */
if (!cmp || !offset_overlap_p (c, xsize, ysize))