[PR87054] fix unaligned access

Building an ADDR_EXPR uses the canonical type to build the pointer
type, but then, as we dereference it, we lose track of lax alignment
known to apply to the dereferenced object.  This might not be a
problem in general, but it is when the compiler implicitly introduces
address taking and dereferencing, as it does for asm statements, and
as it may do in some loop optimizations.

From: Richard Biener <rguenther@suse.de>
for  gcc/ChangeLog

	PR middle-end/87054
	* gimplify.c (gimplify_expr): Retain alignment of
	addressable lvalue in dereference.

From: Alexandre Oliva <oliva@adacore.com>
for  gcc/testsuite/ChangeLog

	PR middle-end/87054
	* gcc.dg/pr87054.c: New.

From-SVN: r264450
This commit is contained in:
Alexandre Oliva 2018-09-20 19:34:44 +00:00
parent 894f597f8f
commit 468e1ef4be
4 changed files with 47 additions and 1 deletions

View File

@ -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

View File

@ -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))
{

View File

@ -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

View File

@ -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
}
}