[PATCH, PR 58041] Make gimple-ssa-strenght-reduction.c create MEM_REFs with alignment information
Richard Biener
rguenther@suse.de
Mon Aug 5 18:18:00 GMT 2013
Martin Jambor <mjambor@suse.cz> wrote:
>Hi,
>
>PR 58041 is a misalignment bug caused by replace_ref in
>gimple-ssa-strength-reduction.c because it does not make sure that the
>MEM_REFs it creates has the proper alignment encoded in them.
>
>I'd like to fix this with the patch below, which basically does the
>same thing SRA does, it is only slightly simpler because we are
>replacing an access to memory with an access to the exact same memory,
>so we don't have to bother computing offset alignments.
>
>I was wondering whether it would make sense to put some common part of
>the code to a function and call it from replace_ref and SRA but such a
>function would probably only contain the align < TYPE_ALIGN check and
>the fold_build_2 call so I was not sure it was worth it. However, I
>may add it as a followup, it may make future users more aware of the
>need to take care of alignment.
>
>I have bootstrapped and tested the patch below on on x86_64-linux,
>Bill Schmidt did the same on powerpc64-unknown-linux-gnu and it also
>got some testing on ARM. OK for trunk (and I think also the 4.8
>branch needs it)?
Ok.
Thanks,
Richard.
>Thanks,
>
>Martin
>
>
>2013-08-05 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.
>
>*** /tmp/5wmq7D_gimple-ssa-strength-reduction.c Mon Aug 5 19:05:06
>2013
>--- gcc/gimple-ssa-strength-reduction.c Mon Aug 5 18:56:10 2013
>*************** dump_incr_vec (void)
>*** 1728,1738 ****
> 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));
>!
>/* 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)
>--- 1728,1750 ----
> static void
> replace_ref (tree *expr, slsr_cand_t c)
> {
>! 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)
>*** /dev/null Fri Aug 2 16:49:33 2013
>--- gcc/testsuite/gcc.dg/torture/pr58041.c Mon Aug 5 18:56:10 2013
>***************
>*** 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;
>+ }
>*** /dev/null Fri Aug 2 16:49:33 2013
>--- gcc/testsuite/gcc.target/arm/pr58041.c Mon Aug 5 19:02:04 2013
>***************
>*** 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;
>+ }
More information about the Gcc-patches
mailing list