diff options
author | Martin Jambor <mjambor@suse.cz> | 2013-08-06 11:22:16 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2013-08-06 11:22:16 +0200 |
commit | 78f6dd686219c887085d40b3dacfb7f1a96aad95 (patch) | |
tree | 730d33490774e04b2abb023fd8b3dd4ca868bf3f /gcc | |
parent | a3d4b3d7dba285bd194463dee6ab6d1e522f53bc (diff) | |
download | gcc-78f6dd686219c887085d40b3dacfb7f1a96aad95.zip gcc-78f6dd686219c887085d40b3dacfb7f1a96aad95.tar.gz gcc-78f6dd686219c887085d40b3dacfb7f1a96aad95.tar.bz2 |
re PR middle-end/58041 (Unaligned access to arrays in packed structure)
2013-08-06 Martin Jambor <mjambor@suse.cz>
PR middle-end/58041
* gimple-ssa-strength-reduction.c (replace_ref): Make sure built
MEM_REF has proper alignment information.
testsuite/
* gcc.dg/torture/pr58041.c: New test.
* gcc.target/arm/pr58041.c: Likewise.
From-SVN: r201523
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-ssa-strength-reduction.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr58041.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/pr58041.c | 30 |
5 files changed, 94 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 394da13..6274c8b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-08-06 Martin Jambor <mjambor@suse.cz> + + PR middle-end/58041 + * gimple-ssa-strength-reduction.c (replace_ref): Make sure built + MEM_REF has proper alignment information. + 2013-08-05 Oleg Endo <olegendo@gcc.gnu.org> PR other/12081 diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index c6f305c..e85e629 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -1728,11 +1728,23 @@ dump_incr_vec (void) static void replace_ref (tree *expr, slsr_cand_t c) { - tree add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr), - c->base_expr, c->stride); - tree mem_ref = fold_build2 (MEM_REF, TREE_TYPE (*expr), add_expr, - double_int_to_tree (c->cand_type, c->index)); - + tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr); + unsigned HOST_WIDE_INT misalign; + unsigned align; + + /* Ensure the memory reference carries the minimum alignment + requirement for the data type. See PR58041. */ + get_object_alignment_1 (*expr, &align, &misalign); + if (misalign != 0) + align = (misalign & -misalign); + if (align < TYPE_ALIGN (acc_type)) + acc_type = build_aligned_type (acc_type, align); + + add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr), + c->base_expr, c->stride); + mem_ref = fold_build2 (MEM_REF, acc_type, add_expr, + double_int_to_tree (c->cand_type, c->index)); + /* Gimplify the base addressing expression for the new MEM_REF tree. */ gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); TREE_OPERAND (mem_ref, 0) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e8ac860..790c556 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-08-06 Martin Jambor <mjambor@suse.cz> + + PR middle-end/58041 + * gcc.dg/torture/pr58041.c: New test. + * gcc.target/arm/pr58041.c: Likewise. + 2013-08-06 Janus Weil <janus@gcc.gnu.org> PR fortran/57306 diff --git a/gcc/testsuite/gcc.dg/torture/pr58041.c b/gcc/testsuite/gcc.dg/torture/pr58041.c new file mode 100644 index 0000000..e22ec3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58041.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +typedef struct S { V v; } P __attribute__((aligned (1))); + +struct s +{ + char u; + V v[2]; +} __attribute__((packed,aligned(1))); + +__attribute__((noinline, noclone)) +long long foo(struct s *x, int y, V z) +{ + V a = x->v[y]; + x->v[y] = z; + return a[1]; +} + +struct s a = {0,{0,0}}; +int main() +{ + V v1 = {0,1}; + V v2 = {0,2}; + + if (foo(&a,0,v1) != 0) + __builtin_abort(); + if (foo(&a,0,v2) != 1) + __builtin_abort(); + if (foo(&a,1,v1) != 0) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/pr58041.c b/gcc/testsuite/gcc.target/arm/pr58041.c new file mode 100644 index 0000000..481a72b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr58041.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -mno-unaligned-access" } */ +/* { dg-final { scan-assembler "ldrb" } } */ +/* { dg-final { scan-assembler "strb" } } */ + +struct s +{ + char u; + long long v[2]; +} __attribute__((packed,aligned(1))); + +__attribute__((noinline, noclone)) +long long foo(struct s *x, int y, long long z) +{ + long long a = x->v[y]; + x->v[y] = z; + return a; +} + +struct s a = {0,{0,0}}; +int main() +{ + if (foo(&a,0,1) != 0) + __builtin_abort(); + if (foo(&a,0,2) != 1) + __builtin_abort(); + if (foo(&a,1,1) != 0) + __builtin_abort(); + return 0; +} |