aboutsummaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2009-01-21 19:47:19 +0100
committerUros Bizjak <uros@gcc.gnu.org>2009-01-21 19:47:19 +0100
commit435da62879db64cab8afd011c4a4cfe010186ab5 (patch)
tree73570de17e026178fe37f390385219209b3654e5 /gcc/alias.c
parentd597b3ce68d904078ca38bca09c5e8984d934364 (diff)
downloadgcc-435da62879db64cab8afd011c4a4cfe010186ab5.zip
gcc-435da62879db64cab8afd011c4a4cfe010186ab5.tar.gz
gcc-435da62879db64cab8afd011c4a4cfe010186ab5.tar.bz2
re PR rtl-optimization/38879 (scheduler does not look for conflicting alias sets)
PR rtl-optimization/38879 * alias.c (base_alias_check): Unaligned access via AND address can alias all surrounding object types except those with sizes equal or wider than the size of unaligned access. From-SVN: r143549
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 18c7d87..13c94bc 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1559,26 +1559,27 @@ base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
if (rtx_equal_p (x_base, y_base))
return 1;
- /* The base addresses of the read and write are different expressions.
- If they are both symbols and 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 alias one another,
- though "char a; long b;" cannot. */
+ /* 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
+ alias one another, though "char a; long b;" cannot. AND addesses may
+ implicitly alias surrounding objects; i.e. unaligned access in DImode
+ via AND address can alias all surrounding object types except those
+ with aligment 8 or higher. */
+ if (GET_CODE (x) == AND && GET_CODE (y) == AND)
+ return 1;
+ if (GET_CODE (x) == AND
+ && (GET_CODE (XEXP (x, 1)) != CONST_INT
+ || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
+ return 1;
+ if (GET_CODE (y) == AND
+ && (GET_CODE (XEXP (y, 1)) != CONST_INT
+ || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
+ return 1;
+
+ /* Differing symbols not accessed via AND never alias. */
if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
- {
- if (GET_CODE (x) == AND && GET_CODE (y) == AND)
- return 1;
- if (GET_CODE (x) == AND
- && (GET_CODE (XEXP (x, 1)) != CONST_INT
- || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
- return 1;
- if (GET_CODE (y) == AND
- && (GET_CODE (XEXP (y, 1)) != CONST_INT
- || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
- return 1;
- /* Differing symbols never alias. */
- return 0;
- }
+ return 0;
/* If one address is a stack reference there can be no alias:
stack references using different base registers do not alias,