On Tue, 28 Feb 2012, Martin Jambor wrote: > Hi, > > the second patch in the series handles MEM_REFs on LHS which are parts > of a handled_component, usually a COMPONENT_REF. The failing testcase > which requires it is not actually the one in the patch but it is > gcc.c-torture/execute/mayalias-3.c which fails at -O1 without this > change but with the third patch applied. > > The mechanism is the same as in the previous patch, it also > piggy-backs a store_bit_field call onto generation of movmisalign > operation, if that is not available but the access would be > SLOW_UNALIGNED_ACCESS. I also needed to add > !mem_ref_refers_to_non_mem_p condition for the same reasons. > Additionally, complex numbers and accesses to their components are > already handled by the existing code (the new testcase passes on all > platforms I tried and so I added it to make sure it continues to) and > actually messing with it further leads to failures (of > g++.dg/torture/pr34099.C at -O1). Therefore I added a condition to > punt on complex modes. > > Thanks, > > Martin > > > 2012-02-28 Martin Jambor <mjam...@suse.cz> > > * expr.c (expand_assignment): Handle misaligned scalar writes to > memory through MEM_REFs within handled_components by calling > store_bit_field. > > * testsuite/gcc.dg/misaligned-expand-3.c: New test. > > > Index: src/gcc/expr.c > =================================================================== > --- src.orig/gcc/expr.c > +++ src/gcc/expr.c > @@ -4575,7 +4575,7 @@ expand_assignment (tree to, tree from, b > rtx result; > enum machine_mode mode; > unsigned int align; > - enum insn_code icode; > + enum insn_code icode = (enum insn_code) 0; > > /* Don't crash if the lhs of the assignment was erroneous. */ > if (TREE_CODE (to) == ERROR_MARK) > @@ -4689,10 +4689,13 @@ expand_assignment (tree to, tree from, b > mode = TYPE_MODE (TREE_TYPE (tem)); > if (TREE_CODE (tem) == MEM_REF > && mode != BLKmode > + && !COMPLEX_MODE_P (mode)
I think the COMPLEX_MODE_P check is not necessary, the cases we explicitely handle would all fall under the mem_ref_refers_to_non_mem_p () case. Ok for stage1 with that change if there are no further comments. Thanks, Richard. > + && !mem_ref_refers_to_non_mem_p (tem) > && ((align = get_object_or_type_alignment (tem)) > < 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))) > { > misalignp = true; > to_rtx = gen_reg_rtx (mode); > @@ -4871,13 +4874,18 @@ expand_assignment (tree to, tree from, b > if (TREE_THIS_VOLATILE (tem)) > MEM_VOLATILE_P (mem) = 1; > > - create_fixed_operand (&ops[0], mem); > - create_input_operand (&ops[1], to_rtx, 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], to_rtx, 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, to_rtx); > } > - > if (result) > preserve_temp_slots (result); > free_temp_slots (); > Index: src/gcc/testsuite/gcc.dg/misaligned-expand-3.c > =================================================================== > --- /dev/null > +++ src/gcc/testsuite/gcc.dg/misaligned-expand-3.c > @@ -0,0 +1,43 @@ > +/* Test that expand can generate correct stores to misaligned data of complex > + type even on strict alignment platforms. */ > + > +/* { dg-do run } */ > +/* { dg-options "-O0" } */ > + > +extern void abort (); > + > +typedef _Complex float mycmplx __attribute__((aligned(1))); > + > +void > +foo (mycmplx *p, float r, float i) > +{ > + __real__ *p = r; > + __imag__ *p = i; > +} > + > +#define cvr 3.2f > +#define cvi 2.5f > +#define NUM 8 > + > +struct blah > +{ > + char c; > + mycmplx x[NUM]; > +} __attribute__((packed)); > + > +struct blah g; > + > +int > +main (int argc, char **argv) > +{ > + int k; > + > + for (k = 0; k < NUM; k++) > + { > + foo (&g.x[k], cvr, cvi); > + if (__real__ g.x[k] != cvr > + || __imag__ g.x[k] != cvi) > + 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