diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimplify.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr87054.c | 29 |
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 + } +} |