diff options
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index 18c7d87a52f..13c94bc6dff 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, |