This fixes PR52402 in a similar way as PR50444. IPA SRA needs to be careful about alignment when constructing accesses.
Bootstrap and regtest pending on x86_64, any comments? Thanks, Richard. 2012-02-27 Richard Guenther <rguent...@suse.de> PR tree-optimization/52402 * ipa-prop.c (ipa_modify_call_arguments): Properly use mis-aligned types when creating the accesses at the call site. * gcc.dg/torture/pr52402.c: New testcase. Index: gcc/ipa-prop.c =================================================================== *** gcc/ipa-prop.c (revision 184591) --- gcc/ipa-prop.c (working copy) *************** ipa_modify_call_arguments (struct cgraph *** 2508,2516 **** } } ! expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off); ! if (adj->by_ref) ! expr = build_fold_addr_expr (expr); expr = force_gimple_operand_gsi (&gsi, expr, adj->by_ref --- 2508,2534 ---- } } ! if (!adj->by_ref) ! { ! tree type = adj->type; ! unsigned int align; ! unsigned HOST_WIDE_INT misalign; ! align = get_pointer_alignment_1 (base, &misalign); ! misalign += (double_int_sext (tree_to_double_int (off), ! TYPE_PRECISION (TREE_TYPE (off))).low ! * BITS_PER_UNIT); ! misalign = misalign & (align - 1); ! if (misalign != 0) ! align = (misalign & -misalign); ! if (align < TYPE_ALIGN (type)) ! type = build_aligned_type (type, align); ! expr = fold_build2_loc (loc, MEM_REF, type, base, off); ! } ! else ! { ! expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off); ! expr = build_fold_addr_expr (expr); ! } expr = force_gimple_operand_gsi (&gsi, expr, adj->by_ref Index: gcc/testsuite/gcc.dg/torture/pr52402.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr52402.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr52402.c (revision 0) *************** *** 0 **** --- 1,28 ---- + /* { dg-do run } */ + + typedef int v4si __attribute__((vector_size(16))); + struct T { v4si i[2]; int j; } __attribute__((packed)); + + static v4si __attribute__((noinline)) + foo (struct T t) + { + return t.i[0]; + } + + static struct T *__attribute__((noinline)) + init () + { + char *p = __builtin_malloc (sizeof (struct T) + 1); + p++; + __builtin_memset (p, 1, sizeof (struct T)); + return (struct T *)p; + } + + int main() + { + struct T *p; + p = init (); + if (foo (*p)[0] != 0x01010101) + __builtin_abort (); + return 0; + }