aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-09-17 09:00:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-09-17 09:00:23 +0000
commitdbad82f59c66cf34d62a4d651736bb92b4b6a4f3 (patch)
tree4a30594d5197d1ab67d4bb385ff0565f90546283 /gcc
parent52b3b3c7e24d8ef6de75310eb4a1437f45c1f469 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/builtins.c49
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);