aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimplify.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr87054.c29
4 files changed, 47 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 641e359..361dfc4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-20 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/87054
+ * gimplify.c (gimplify_expr): Retain alignment of
+ addressable lvalue in dereference.
+
2018-09-20 Alexandre Oliva <aoliva@redhat.com>
PR bootstrap/87013
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index f0eb04a..509fc2f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -12538,9 +12538,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
/* An lvalue will do. Take the address of the expression, store it
in a temporary, and replace the expression with an INDIRECT_REF of
that temporary. */
+ tree ref_alias_type = reference_alias_ptr_type (*expr_p);
+ unsigned int ref_align = get_object_alignment (*expr_p);
+ tree ref_type = TREE_TYPE (*expr_p);
tmp = build_fold_addr_expr_loc (input_location, *expr_p);
gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
- *expr_p = build_simple_mem_ref (tmp);
+ if (TYPE_ALIGN (ref_type) != ref_align)
+ ref_type = build_aligned_type (ref_type, ref_align);
+ *expr_p = build2 (MEM_REF, ref_type,
+ tmp, build_zero_cst (ref_alias_type));
}
else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c7c8e90..a0a08a4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-20 Alexandre Oliva <oliva@adacore.com>
+
+ PR middle-end/87054
+ * gcc.dg/pr87054.c: New.
+
2018-09-20 Richard Sandiford <richard.sandiford@arm.com>
PR tree-optimization/87288
diff --git a/gcc/testsuite/gcc.dg/pr87054.c b/gcc/testsuite/gcc.dg/pr87054.c
new file mode 100644
index 0000000..4ca2b62
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr87054.c
@@ -0,0 +1,29 @@
+// { dg-do run }
+// { dg-options "-O2" }
+
+#ifndef T
+# ifdef __SSE__
+# define T __int128
+# else
+# define T long
+# endif
+#endif
+#ifndef R
+# ifdef __SSE__
+# define R "x"
+# else
+# define R "r"
+# endif
+#endif
+
+
+typedef T A; // #define T to long or __int128
+struct B { char d; A c; } __attribute__((packed));
+struct B b[50]; // many elements to avoid loop unrolling
+
+int main () {
+ int i;
+ for (i = 0; i < sizeof(b) / sizeof(*b); i++) {
+ asm ("" : "+" R (b[i].c)); // #define R to "r" on ppc or "x" on x86_64
+ }
+}