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 <mjam...@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 <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer