aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2013-08-06 11:22:16 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2013-08-06 11:22:16 +0200
commit78f6dd686219c887085d40b3dacfb7f1a96aad95 (patch)
tree730d33490774e04b2abb023fd8b3dd4ca868bf3f /gcc
parenta3d4b3d7dba285bd194463dee6ab6d1e522f53bc (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/gimple-ssa-strength-reduction.c22
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58041.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/pr58041.c30
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;
+}