On Tue, 7 Apr 2020, Martin Jambor wrote:

> Hi,
> 
> when sra_modify_expr is invoked on an expression that modifies only
> part of the underlying replacement, such as a BIT_FIELD_REF on a LHS
> of an assignment and the SRA replacement's type is not compatible with
> what is being replaced (0th operand of the B_F_R in the above
> example), it does not work properly, basically throwing away the partd
> of the expr that should have stayed intact.
> 
> This is fixed in two ways.  For BIT_FIELD_REFs, which operate on the
> binary image of the replacement (and so in a way serve as a
> VIEW_CONVERT_EXPR) we just do not bother with convertsing.  For
> REALPART_EXPRs and IMAGPART_EXPRs, we insert a VIEW_CONVERT_EXPR under
> the complex partial access expression, which is OK even in a LHS of an
> assignment (and other write contexts) because in those cases the
> replacement is not going to be a giple register anyway.
> 
> The testcase for handling REALPART_EXPR and IMAGPART_EXPR is a bit
> fragile because SRA prefers complex and vector types over anything else
> (and in between the two it decides based on TYPE_UID which in my testing
> today always preferred complex types) and even when GIMPLE is wrong I
> often still did not get failing runs, so I only run it at -O1 (which is
> the only level where the the test fails for me).
> 
> Bootstrapped and tested on x86_64-linux, bootstrap and testing on
> i686-linux and aarch64-linux underway.
> 
> OK for trunk (and subsequently for release branches) if it passes?

OK.

generate_subtree_copies contains similar code and the call in
sra_modify_expr suggests that an (outer?) bit-field-ref is possible
here, so is generate_subtree_copies affected as well?  I'm not sure
how subtree copy generation "works" when we already replaced sth
but maybe access->grp_to_be_replaced is never true when
access->first_child is not NULL?  But then we still pass down
the "stripped" orig_expr (op0 of BIT_FIELD_REF/REALPART_EXPR).

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 2020-04-06  Martin Jambor  <mjam...@suse.cz>
> 
>       PR tree-optimization/94482
>       * tree-sra.c (create_access_replacement): Dump new replacement with
>       TDF_UID.
>       (sra_modify_expr): Fix handling of cases when the original EXPR writes
>       to only part of the replacement.
> 
>       testsuite/
>       * gcc.dg/torture/pr94482.c: New test.
>       * gcc.dg/tree-ssa/pr94482-2.c: Likewise.
> ---
>  gcc/ChangeLog                             |  8 ++++
>  gcc/testsuite/ChangeLog                   |  6 +++
>  gcc/testsuite/gcc.dg/torture/pr94482.c    | 34 +++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c | 50 +++++++++++++++++++++++
>  gcc/tree-sra.c                            | 17 ++++++--
>  5 files changed, 111 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr94482.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index e10fb251c16..36ddef64afd 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,11 @@
> +2020-04-06  Martin Jambor  <mjam...@suse.cz>
> +
> +     PR tree-optimization/94482
> +     * tree-sra.c (create_access_replacement): Dump new replacement with
> +     TDF_UID.
> +     (sra_modify_expr): Fix handling of cases when the original EXPR writes
> +     to only part of the replacement.
> +
>  2020-04-05 Zachary Spytz  <zsp...@gmail.com>
>  
>       * extend.texi: Add free to list of ISO C90 functions that
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 88bab5d3d19..8b85e55afe8 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,9 @@
> +2020-04-06  Martin Jambor  <mjam...@suse.cz>
> +
> +     PR tree-optimization/94482
> +     * gcc.dg/torture/pr94482.c: New test.
> +     * gcc.dg/tree-ssa/pr94482-2.c: Likewise.
> +
>  2020-04-05  Iain Sandoe  <i...@sandoe.co.uk>
>  
>       * g++.dg/coroutines/torture/co-await-14-template-traits.C: Rename...
> diff --git a/gcc/testsuite/gcc.dg/torture/pr94482.c 
> b/gcc/testsuite/gcc.dg/torture/pr94482.c
> new file mode 100644
> index 00000000000..5bb19e745c2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/pr94482.c
> @@ -0,0 +1,34 @@
> +/* { dg-do run } */
> +
> +typedef unsigned V __attribute__ ((__vector_size__ (16)));
> +union U
> +{
> +  V j;
> +  unsigned long long i __attribute__ ((__vector_size__ (16)));
> +};
> +
> +static inline __attribute__((always_inline)) V
> +foo (unsigned long long a)
> +{
> +  union U z = { .j = (V) {} };
> +  for (unsigned long i = 0; i < 1; i++)
> +    z.i[i] = a;
> +  return z.j;
> +}
> +
> +static inline __attribute__((always_inline)) V
> +bar (V a, unsigned long long i, int q)
> +{
> +  union U z = { .j = a };
> +  z.i[q] = i;
> +  return z.j;
> +}
> +
> +int
> +main ()
> +{
> +  union U z = { .j = bar (foo (1729), 2, 1) };
> +  if (z.i[0] != 1729)
> +    __builtin_abort ();
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c
> new file mode 100644
> index 00000000000..fcac9d5e439
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c
> @@ -0,0 +1,50 @@
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +
> +typedef unsigned long V __attribute__ ((__vector_size__ (8)));
> +typedef _Complex int Ci;
> +typedef _Complex float Cf;
> +
> +union U
> +{
> +  Ci ci;
> +  Cf cf;
> +};
> +
> +volatile Ci vgi;
> +
> +Cf foo (Cf c)
> +{
> +  __real c = 0x1ffp10;
> +  return c;
> +}
> +
> +Ci ioo (Ci c)
> +{
> +  __real c = 50;
> +  return c;
> +}
> +
> +
> +int main (int argc, char *argv[])
> +{
> +  union U u;
> +
> +  __real u.ci = 500;
> +  __imag u.ci = 1000;
> +  vgi = u.ci;
> +
> +  u.ci = ioo (u.ci);
> +  __imag u.ci = 100;
> +
> +  if (__real u.ci != 50 || __imag u.ci != 100)
> +    __builtin_abort();
> +
> +  u.cf = foo (u.cf);
> +  __imag u.cf = 0x1p3;
> +
> +  if (__real u.cf != 0x1ffp10 || __imag u.cf != 0x1p3)
> +    __builtin_abort();
> +
> +  return 0;
> +}
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index b2056b58750..494ab609149 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -2257,7 +2257,7 @@ create_access_replacement (struct access *access, tree 
> reg_type = NULL_TREE)
>         print_generic_expr (dump_file, access->base);
>         fprintf (dump_file, " offset: %u, size: %u: ",
>                  (unsigned) access->offset, (unsigned) access->size);
> -       print_generic_expr (dump_file, repl);
> +       print_generic_expr (dump_file, repl, TDF_UID);
>         fprintf (dump_file, "\n");
>       }
>      }
> @@ -3698,6 +3698,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, 
> bool write)
>    location_t loc;
>    struct access *access;
>    tree type, bfr, orig_expr;
> +  bool partial_cplx_access = false;
>  
>    if (TREE_CODE (*expr) == BIT_FIELD_REF)
>      {
> @@ -3708,7 +3709,10 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator 
> *gsi, bool write)
>      bfr = NULL_TREE;
>  
>    if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == 
> IMAGPART_EXPR)
> -    expr = &TREE_OPERAND (*expr, 0);
> +    {
> +      expr = &TREE_OPERAND (*expr, 0);
> +      partial_cplx_access = true;
> +    }
>    access = get_access_for_expr (*expr);
>    if (!access)
>      return false;
> @@ -3736,13 +3740,18 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator 
> *gsi, bool write)
>           be accessed as a different type too, potentially creating a need for
>           type conversion (see PR42196) and when scalarized unions are 
> involved
>           in assembler statements (see PR42398).  */
> -      if (!useless_type_conversion_p (type, access->type))
> +      if (!bfr && !useless_type_conversion_p (type, access->type))
>       {
>         tree ref;
>  
>         ref = build_ref_for_model (loc, orig_expr, 0, access, gsi, false);
>  
> -       if (write)
> +       if (partial_cplx_access)
> +         /* VIEW_CONVERT_EXPRs in partial complex access are fine even in
> +            the case of a write because in such case the replacement cannot
> +            be a gimple register.  */
> +         *expr = build1 (VIEW_CONVERT_EXPR, type, repl);
> +       else if (write)
>           {
>             gassign *stmt;
>  
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to