diff options
author | Richard Guenther <rguenther@suse.de> | 2010-09-17 09:00:23 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-09-17 09:00:23 +0000 |
commit | dbad82f59c66cf34d62a4d651736bb92b4b6a4f3 (patch) | |
tree | 4a30594d5197d1ab67d4bb385ff0565f90546283 /gcc | |
parent | 52b3b3c7e24d8ef6de75310eb4a1437f45c1f469 (diff) | |
download | gcc-dbad82f59c66cf34d62a4d651736bb92b4b6a4f3.zip gcc-dbad82f59c66cf34d62a4d651736bb92b4b6a4f3.tar.gz gcc-dbad82f59c66cf34d62a4d651736bb92b4b6a4f3.tar.bz2 |
re PR rtl-optimization/45678 (crash on vector code with -m32 -msse)
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.
From-SVN: r164356
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/builtins.c | 49 |
2 files changed, 41 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7625ff3..04eeac7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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. + 2010-09-16 Jan Hubicka <jh@suse.cz> * lto-cgraph.c (input_overwrite_node): Do not set DECL_EXTERNAL when diff --git a/gcc/builtins.c b/gcc/builtins.c index 2dd6119..384a81a 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); |