This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, PR 49094] Refrain from creating misaligned accesses in SRA
Hi,
On Thu, Jun 30, 2011 at 03:39:55PM +0200, Martin Jambor wrote:
> Hi,
>
> I had to add a test that the analyzed expression is not an SSA name.
> This has been approved by Rchi on IRC yesterday. Thus, I have
> committed the following as revision 175703 after successful run of c
> and c++ testsuite on sparc64 (and a bootstrap and test with another
> patch on x86_64-linux).
I also tested fortran on sparc64 but missed a regression there
(gfortran.dg/pr25923.f90). The problem is that *arg_1(D) is also
scrutinized, get_object_alignment returns 8 for it and that is
obviously not enough for SImode required alignment.
I assume such loads have to be aligned for the mode on strict aligned
targets and therefore they are OK. The question is, is that true for
all MEM_REFs or only for those with zero offset? Since the original
problem was that the expander expanded
MEM[(struct ip *)ip_3 + 7B].s_addr;
as if it was aligned, I suppose that MEM_REFs are generally fine and
we can avoid this issue by skipping them just like the SSA_NAMEs. Is
my reasoning correct?
Thanks,
Martin
>
> Thanks,
>
> Martin
>
>
> 2011-06-30 Martin Jambor <mjambor@suse.cz>
>
> PR tree-optimization/49094
> * tree-sra.c (tree_non_mode_aligned_mem_p): New function.
> (build_accesses_from_assign): Use it.
>
> * testsuite/gcc.dg/tree-ssa/pr49094.c: New test.
>
>
> Index: src/gcc/tree-sra.c
> ===================================================================
> --- src.orig/gcc/tree-sra.c
> +++ src/gcc/tree-sra.c
> @@ -1050,6 +1050,26 @@ disqualify_ops_if_throwing_stmt (gimple
> return false;
> }
>
> +/* Return true iff type of EXP is not sufficiently aligned. */
> +
> +static bool
> +tree_non_mode_aligned_mem_p (tree exp)
> +{
> + enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
> + unsigned int align;
> +
> + if (TREE_CODE (exp) == SSA_NAME
> + || mode == BLKmode
> + || !STRICT_ALIGNMENT)
> + return false;
> +
> + align = get_object_alignment (exp, BIGGEST_ALIGNMENT);
> + if (GET_MODE_ALIGNMENT (mode) > align)
> + return true;
> +
> + return false;
> +}
> +
> /* Scan expressions occuring in STMT, create access structures for all accesses
> to candidates for scalarization and remove those candidates which occur in
> statements or expressions that prevent them from being split apart. Return
> @@ -1074,7 +1094,10 @@ build_accesses_from_assign (gimple stmt)
> lacc = build_access_from_expr_1 (lhs, stmt, true);
>
> if (lacc)
> - lacc->grp_assignment_write = 1;
> + {
> + lacc->grp_assignment_write = 1;
> + lacc->grp_unscalarizable_region |= tree_non_mode_aligned_mem_p (rhs);
> + }
>
> if (racc)
> {
> @@ -1082,6 +1105,7 @@ build_accesses_from_assign (gimple stmt)
> if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
> && !is_gimple_reg_type (racc->type))
> bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
> + racc->grp_unscalarizable_region |= tree_non_mode_aligned_mem_p (lhs);
> }
>
> if (lacc && racc
> Index: src/gcc/testsuite/gcc.dg/tree-ssa/pr49094.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/tree-ssa/pr49094.c
> @@ -0,0 +1,38 @@
> +/* { dg-do run } */
> +/* { dg-options "-O" } */
> +
> +struct in_addr {
> + unsigned int s_addr;
> +};
> +
> +struct ip {
> + unsigned char ip_p;
> + unsigned short ip_sum;
> + struct in_addr ip_src,ip_dst;
> +} __attribute__ ((aligned(1), packed));
> +
> +struct ip ip_fw_fwd_addr;
> +
> +int test_alignment( char *m )
> +{
> + struct ip *ip = (struct ip *) m;
> + struct in_addr pkt_dst;
> + pkt_dst = ip->ip_dst ;
> + if( pkt_dst.s_addr == 0 )
> + return 1;
> + else
> + return 0;
> +}
> +
> +int __attribute__ ((noinline, noclone))
> +intermediary (char *p)
> +{
> + return test_alignment (p);
> +}
> +
> +int
> +main (int argc, char *argv[])
> +{
> + ip_fw_fwd_addr.ip_dst.s_addr = 1;
> + return intermediary ((void *) &ip_fw_fwd_addr);
> +}