re PR middle-end/58041 (Unaligned access to arrays in packed structure)

2013-08-06  Martin Jambor  <mjambor@suse.cz>

	PR middle-end/58041
	* gimple-ssa-strength-reduction.c (replace_ref): Make sure built
	MEM_REF has proper alignment information.

testsuite/
	* gcc.dg/torture/pr58041.c: New test.
	* gcc.target/arm/pr58041.c: Likewise.

From-SVN: r201523
This commit is contained in:
Martin Jambor 2013-08-06 11:22:16 +02:00 committed by Martin Jambor
parent a3d4b3d7db
commit 78f6dd6862
5 changed files with 94 additions and 5 deletions

View file

@ -1,3 +1,9 @@
2013-08-06 Martin Jambor <mjambor@suse.cz>
PR middle-end/58041
* gimple-ssa-strength-reduction.c (replace_ref): Make sure built
MEM_REF has proper alignment information.
2013-08-05 Oleg Endo <olegendo@gcc.gnu.org>
PR other/12081

View file

@ -1728,11 +1728,23 @@ dump_incr_vec (void)
static void
replace_ref (tree *expr, slsr_cand_t c)
{
tree add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
c->base_expr, c->stride);
tree mem_ref = fold_build2 (MEM_REF, TREE_TYPE (*expr), add_expr,
double_int_to_tree (c->cand_type, c->index));
tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr);
unsigned HOST_WIDE_INT misalign;
unsigned align;
/* Ensure the memory reference carries the minimum alignment
requirement for the data type. See PR58041. */
get_object_alignment_1 (*expr, &align, &misalign);
if (misalign != 0)
align = (misalign & -misalign);
if (align < TYPE_ALIGN (acc_type))
acc_type = build_aligned_type (acc_type, align);
add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
c->base_expr, c->stride);
mem_ref = fold_build2 (MEM_REF, acc_type, add_expr,
double_int_to_tree (c->cand_type, c->index));
/* Gimplify the base addressing expression for the new MEM_REF tree. */
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
TREE_OPERAND (mem_ref, 0)

View file

@ -1,3 +1,9 @@
2013-08-06 Martin Jambor <mjambor@suse.cz>
PR middle-end/58041
* gcc.dg/torture/pr58041.c: New test.
* gcc.target/arm/pr58041.c: Likewise.
2013-08-06 Janus Weil <janus@gcc.gnu.org>
PR fortran/57306

View file

@ -0,0 +1,35 @@
/* { dg-do run } */
typedef long long V
__attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
typedef struct S { V v; } P __attribute__((aligned (1)));
struct s
{
char u;
V v[2];
} __attribute__((packed,aligned(1)));
__attribute__((noinline, noclone))
long long foo(struct s *x, int y, V z)
{
V a = x->v[y];
x->v[y] = z;
return a[1];
}
struct s a = {0,{0,0}};
int main()
{
V v1 = {0,1};
V v2 = {0,2};
if (foo(&a,0,v1) != 0)
__builtin_abort();
if (foo(&a,0,v2) != 1)
__builtin_abort();
if (foo(&a,1,v1) != 0)
__builtin_abort();
return 0;
}

View file

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-Os -mno-unaligned-access" } */
/* { dg-final { scan-assembler "ldrb" } } */
/* { dg-final { scan-assembler "strb" } } */
struct s
{
char u;
long long v[2];
} __attribute__((packed,aligned(1)));
__attribute__((noinline, noclone))
long long foo(struct s *x, int y, long long z)
{
long long a = x->v[y];
x->v[y] = z;
return a;
}
struct s a = {0,{0,0}};
int main()
{
if (foo(&a,0,1) != 0)
__builtin_abort();
if (foo(&a,0,2) != 1)
__builtin_abort();
if (foo(&a,1,1) != 0)
__builtin_abort();
return 0;
}