diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-29 09:42:42 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-29 09:42:42 +0000 |
commit | 0d8f7716f77fdebd8615437c85a9306da0c9f9f4 (patch) | |
tree | 959a91c1ec3ac4f1dfeb6120dc9880fdef666220 /gcc/builtins.c | |
parent | 6eb047a38bde5de9ee138d5d2c2d392aeaa64f0a (diff) | |
download | gcc-0d8f7716f77fdebd8615437c85a9306da0c9f9f4.tar.gz |
gcc/
PR tree-optimization/49545
* builtins.c (get_object_alignment_1): Update function comment.
Do not use DECL_ALIGN for functions, but test
TARGET_PTRMEMFUNC_VBIT_LOCATION instead.
* fold-const.c (get_pointer_modulus_and_residue): Don't check
for functions here.
* tree-ssa-ccp.c (get_value_from_alignment): Likewise.
gcc/testsuite/
* gcc.dg/torture/pr49169.c: Restrict to ARM and MIPS targets.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175627 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 0747e04a3af..1ee8cf80001 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -264,8 +264,15 @@ called_as_built_in (tree node) return is_builtin_name (name); } -/* Return the alignment in bits of EXP, an object. - Don't return more than MAX_ALIGN no matter what. */ +/* Compute values M and N such that M divides (address of EXP - N) and + such that N < M. Store N in *BITPOSP and return M. + + Note that the address (and thus the alignment) computed here is based + on the address to which a symbol resolves, whereas DECL_ALIGN is based + on the address at which an object is actually located. These two + addresses are not always the same. For example, on ARM targets, + the address &foo of a Thumb function foo() has the lowest bit set, + whereas foo() itself starts on an even address. */ unsigned int get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) @@ -287,7 +294,21 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) exp = DECL_INITIAL (exp); if (DECL_P (exp) && TREE_CODE (exp) != LABEL_DECL) - align = DECL_ALIGN (exp); + { + if (TREE_CODE (exp) == FUNCTION_DECL) + { + /* Function addresses can encode extra information besides their + alignment. However, if TARGET_PTRMEMFUNC_VBIT_LOCATION + allows the low bit to be used as a virtual bit, we know + that the address itself must be 2-byte aligned. */ + if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) + align = 2 * BITS_PER_UNIT; + else + align = BITS_PER_UNIT; + } + else + align = DECL_ALIGN (exp); + } else if (CONSTANT_CLASS_P (exp)) { align = TYPE_ALIGN (TREE_TYPE (exp)); |