On Wed, Apr 08 2020, Martin Jambor wrote:
>
[...]
>
> 2020-04-08  Martin Jambor  <mjam...@suse.cz>
>           Richard Biener  <rguent...@suse.de>
>
>       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.
>       * tree-ssa-forwprop.c (pass_forwprop::execute): Properly verify
>       the first operand of combinations into REAL/IMAGPART_EXPR and
>       BIT_FIELD_REF.
>
>       testsuite/
>       * gcc.dg/torture/pr94482.c: New test.
>       * gcc.dg/tree-ssa/pr94482-2.c: Likewise.

I'd like to backport the patch to the gcc-9 and gcc-8 branches.  The
backport patch is the same for both release branches, the differences
compared to the mainline one are:

1. the code handling BIT_FIELD_REF if fwprop is not present on the
   release branches so the "fixing" hunk was dropped, and

2. the testcase options were changed to what Jakub put there on
   the mainline to suppress all vector ABI warnings.

Bootstrapped and tested on x86_64-linux.  OK for both?

Thanks,

Martin


2020-04-21  Martin Jambor  <mjam...@suse.cz>

        Backport from master
        2020-04-09  Martin Jambor  <mjam...@suse.cz>
                    Richard Biener  <rguent...@suse.de>

        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.
        * tree-ssa-forwprop.c (pass_forwprop::execute): Properly verify
        the first operand of combinations into REAL/IMAGPART_EXPR and
        BIT_FIELD_REF.

        testsuite/
        * gcc.dg/torture/pr94482.c: New test.
        * gcc.dg/tree-ssa/pr94482-2.c: Likewise.
---
 gcc/ChangeLog                             | 15 +++++++
 gcc/testsuite/ChangeLog                   |  9 ++++
 gcc/testsuite/gcc.dg/torture/pr94482.c    | 36 ++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr94482-2.c | 50 +++++++++++++++++++++++
 gcc/tree-sra.c                            | 31 ++++++++++++--
 gcc/tree-ssa-forwprop.c                   |  3 +-
 6 files changed, 139 insertions(+), 5 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 7df3a0d0990..be843b53e6c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2020-04-21  Martin Jambor  <mjam...@suse.cz>
+
+       Backport from master
+       2020-04-09  Martin Jambor  <mjam...@suse.cz>
+                   Richard Biener  <rguent...@suse.de>
+
+       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.
+       * tree-ssa-forwprop.c (pass_forwprop::execute): Properly verify
+       the first operand of combinations into REAL/IMAGPART_EXPR and
+       BIT_FIELD_REF.
+
 2020-04-17  H.J. Lu  <hongjiu...@intel.com>
 
        Backport from master
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3df9dd78d0c..248244343c4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2020-04-21  Martin Jambor  <mjam...@suse.cz>
+
+       Backport from master
+       2020-04-09  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-17  H.J. Lu  <hongjiu...@intel.com>
 
        Backport from master
diff --git a/gcc/testsuite/gcc.dg/torture/pr94482.c 
b/gcc/testsuite/gcc.dg/torture/pr94482.c
new file mode 100644
index 00000000000..9264842e349
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr94482.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-additional-options "-Wno-psabi -w" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+
+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 0a5c24a183a..805839cac50 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2329,7 +2329,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");
        }
     }
@@ -3187,6 +3187,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)
     {
@@ -3197,7 +3198,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;
@@ -3225,13 +3229,32 @@ 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 always fine in
+              the case of a write because in such case the replacement cannot
+              be a gimple register.  In the case of a load, we have to
+              differentiate in between a register an non-register
+              replacement.  */
+             tree t = build1 (VIEW_CONVERT_EXPR, type, repl);
+             gcc_checking_assert (!write || access->grp_partial_lhs);
+             if (!access->grp_partial_lhs)
+               {
+                 tree tmp = make_ssa_name (type);
+                 gassign *stmt = gimple_build_assign (tmp, t);
+                 /* This is always a read. */
+                 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+                 t = tmp;
+               }
+             *expr = t;
+           }
+         else if (write)
            {
              gassign *stmt;
 
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index bbfa1bc6fae..ca5443b79b3 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2357,7 +2357,8 @@ pass_forwprop::execute (function *fun)
                    continue;
                  if (!is_gimple_assign (use_stmt)
                      || (gimple_assign_rhs_code (use_stmt) != REALPART_EXPR
-                         && gimple_assign_rhs_code (use_stmt) != 
IMAGPART_EXPR))
+                         && gimple_assign_rhs_code (use_stmt) != IMAGPART_EXPR)
+                     || TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) != lhs)
                    {
                      rewrite = false;
                      break;
-- 
2.26.0

Reply via email to