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

Reply via email to