[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:
parent
894f597f8f
commit
468e1ef4be
@ -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
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
29
gcc/testsuite/gcc.dg/pr87054.c
Normal file
29
gcc/testsuite/gcc.dg/pr87054.c
Normal 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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user