diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-17 09:00:23 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-17 09:00:23 +0000 |
commit | 5b99ff01d0f288316fb391c4053b25d769bce546 (patch) | |
tree | 4a30594d5197d1ab67d4bb385ff0565f90546283 /gcc/builtins.c | |
parent | cdc58a668b4cdcbdd4cc885abcb52bad2aedd8b9 (diff) | |
download | gcc-5b99ff01d0f288316fb391c4053b25d769bce546.tar.gz |
2010-09-17 Richard Guenther <rguenther@suse.de>
PR middle-end/45678
* builtins.c (fold_builtin_memory_op): Always properly adjust
alignment of memory accesses.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164356 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 2dd6119c782..384a81a035b 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8555,12 +8555,21 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, STRIP_NOPS (srcvar); if (TREE_CODE (srcvar) == ADDR_EXPR && var_decl_component_p (TREE_OPERAND (srcvar, 0)) - && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len) - && (!STRICT_ALIGNMENT - || !destvar - || src_align >= TYPE_ALIGN (desttype))) - srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype, - srcvar, off0); + && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)) + { + if (!destvar + || src_align >= TYPE_ALIGN (desttype)) + srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype, + srcvar, off0); + else if (!STRICT_ALIGNMENT) + { + srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype), + src_align); + srcvar = fold_build2 (MEM_REF, srctype, srcvar, off0); + } + else + srcvar = NULL_TREE; + } else srcvar = NULL_TREE; @@ -8569,19 +8578,31 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, if (srcvar == NULL_TREE) { - if (STRICT_ALIGNMENT - && src_align < TYPE_ALIGN (desttype)) - return NULL_TREE; STRIP_NOPS (src); - srcvar = fold_build2 (MEM_REF, desttype, src, off0); + if (src_align >= TYPE_ALIGN (desttype)) + srcvar = fold_build2 (MEM_REF, desttype, src, off0); + else + { + if (STRICT_ALIGNMENT) + return NULL_TREE; + srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype), + src_align); + srcvar = fold_build2 (MEM_REF, srctype, src, off0); + } } else if (destvar == NULL_TREE) { - if (STRICT_ALIGNMENT - && dest_align < TYPE_ALIGN (srctype)) - return NULL_TREE; STRIP_NOPS (dest); - destvar = fold_build2 (MEM_REF, srctype, dest, off0); + if (dest_align >= TYPE_ALIGN (srctype)) + destvar = fold_build2 (MEM_REF, srctype, dest, off0); + else + { + if (STRICT_ALIGNMENT) + return NULL_TREE; + desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype), + dest_align); + destvar = fold_build2 (MEM_REF, desttype, dest, off0); + } } expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, srcvar); |