diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 641e3591040ffeaa3283aa0786a36434bd3b188a..361dfc468a1712dffb58657cd18a3c16bfe5a19a 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 f0eb04a751ccc64ebeb5ba695ebf31f7b5758cec..509fc2f3f5be20985558e8b4f2e94a7cbf814567 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 c7c8e90b27c5670f7264285d75f3e2ef417201d7..a0a08a4d499856a1cb8712b3851c66a01e566cb5 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 0000000000000000000000000000000000000000..4ca2b62d2c7c97516c7032dd3f253cde4986127e --- /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 + } +}