This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC PATCH 1/3] Misaligned top level MEM_REFs on LHS of assignments
On Tue, 28 Feb 2012, Martin Jambor wrote:
> Hi,
>
> the first patch in the series deals with plain MEM_REFs on LHS of
> assignments to handle situations such as the testcase which currently
> fails on strict alignment platforms (the array and the loop are there
> to cross a cache line on ia64 so that it fails there too).
>
> This patch piggy-backs on already existing code for generating
> movmisalign operation if available, and deals with the store by
> calling store_bit_field if it is not but it would be a
> SLOW_UNALIGNED_ACCESS.
>
> I have added !mem_ref_refers_to_non_mem_p (to) to the condition
> guarding both of these paths because without it I encountered
> testsuite failures within expand_expr when the MEM_REF address
> argument was expanded into something else than memory. This call is
> common for both movmisalign_optab and store_bit_field paths so I
> believe it is necessary on both but so far I did not come up with a
> testcase in which it would fail with movmisalign.
This patch is ok for stage1 if it bootstraps & tests ok and there
are no further comments.
Thanks,
Richard.
> Thanks,
>
> Martin
>
>
>
> 2012-02-28 Martin Jambor <mjambor@suse.cz>
>
> * expr.c (expand_assignment): Handle misaligned scalar writes to
> memory through top-level MEM_REFs by calling store_bit_field.
>
> * testsuite/gcc.dg/misaligned-expand-2.c: New test.
>
>
> Index: src/gcc/expr.c
> ===================================================================
> --- src.orig/gcc/expr.c
> +++ src/gcc/expr.c
> @@ -4593,10 +4593,12 @@ expand_assignment (tree to, tree from, b
> if ((TREE_CODE (to) == MEM_REF
> || TREE_CODE (to) == TARGET_MEM_REF)
> && mode != BLKmode
> + && !mem_ref_refers_to_non_mem_p (to)
> && ((align = get_object_or_type_alignment (to))
> < GET_MODE_ALIGNMENT (mode))
> - && ((icode = optab_handler (movmisalign_optab, mode))
> - != CODE_FOR_nothing))
> + && (((icode = optab_handler (movmisalign_optab, mode))
> + != CODE_FOR_nothing)
> + || SLOW_UNALIGNED_ACCESS (mode, align)))
> {
> addr_space_t as
> = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 0))));
> @@ -4639,11 +4641,17 @@ expand_assignment (tree to, tree from, b
> if (TREE_THIS_VOLATILE (to))
> MEM_VOLATILE_P (mem) = 1;
>
> - create_fixed_operand (&ops[0], mem);
> - create_input_operand (&ops[1], reg, mode);
> - /* The movmisalign<mode> pattern cannot fail, else the assignment would
> - silently be omitted. */
> - expand_insn (icode, 2, ops);
> + if (icode != CODE_FOR_nothing)
> + {
> + create_fixed_operand (&ops[0], mem);
> + create_input_operand (&ops[1], reg, mode);
> + /* The movmisalign<mode> pattern cannot fail, else the assignment would
> + silently be omitted. */
> + expand_insn (icode, 2, ops);
> + }
> + else
> + store_bit_field (mem, GET_MODE_BITSIZE (mode),
> + 0, 0, 0, mode, reg);
> return;
> }
>
> Index: src/gcc/testsuite/gcc.dg/misaligned-expand-2.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/misaligned-expand-2.c
> @@ -0,0 +1,42 @@
> +/* Test that expand can generate correct stores to misaligned data even on
> + strict alignment platforms. */
> +
> +/* { dg-do run } */
> +/* { dg-options "-O0" } */
> +
> +extern void abort ();
> +
> +typedef unsigned int myint __attribute__((aligned(1)));
> +
> +void
> +foo (myint *p, unsigned int i)
> +{
> + *p = i;
> +}
> +
> +#define cst 0xdeadbeef
> +#define NUM 8
> +
> +struct blah
> +{
> + char c;
> + myint i[NUM];
> +};
> +
> +struct blah g;
> +
> +#define cst 0xdeadbeef
> +
> +int
> +main (int argc, char **argv)
> +{
> + int k;
> +
> + for (k = 0; k < NUM; k++)
> + {
> + foo (&g.i[k], cst);
> + if (g.i[k] != cst)
> + abort ();
> + }
> + return 0;
> +}
>
>
--
Richard Guenther <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer