This fixes a hole that still allowed forwarding of TARGET_MEM_REF
addresses.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2020-05-25  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/95308
        * tree-ssa-forwprop.c (pass_forwprop::execute): Generalize
        test for TARGET_MEM_REFs.

        * g++.dg/torture/pr95308.C: New testcase.
---
 gcc/testsuite/g++.dg/torture/pr95308.C | 21 +++++++++++++++++++++
 gcc/tree-ssa-forwprop.c                | 14 +++++++-------
 2 files changed, 28 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr95308.C

diff --git a/gcc/testsuite/g++.dg/torture/pr95308.C 
b/gcc/testsuite/g++.dg/torture/pr95308.C
new file mode 100644
index 00000000000..01aa8ad17a6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr95308.C
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-additional-options "-march=skylake-avx512" { target x86_64-*-* 
i?86-*-* } }
+
+extern int a[][18];
+extern short b[], c[];
+extern char d[][18];
+int e;
+void i(char f, long g[][100][100][100])
+{
+  for (int h = 0;; h += 2)
+    for (char j = 0; j < 17; j++) {
+       if (e ? f : 0) {
+           a[h][j] = 5;
+           for (int k = 0; k < 12; k += 4)
+             for (short l = 0; l < 015; l += 2)
+               b[k * 3 + l] = bool(g[2][j][k][l]);
+       } else
+         d[h][j] = 0;
+       c[j] = 3;
+    }
+}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index b2ea3622d70..759baf56897 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2763,18 +2763,18 @@ pass_forwprop::execute (function *fun)
 
          /* If this statement sets an SSA_NAME to an address,
             try to propagate the address into the uses of the SSA_NAME.  */
-         if (code == ADDR_EXPR
-             /* Handle pointer conversions on invariant addresses
-                as well, as this is valid gimple.  */
-             || (CONVERT_EXPR_CODE_P (code)
-                 && TREE_CODE (rhs) == ADDR_EXPR
-                 && POINTER_TYPE_P (TREE_TYPE (lhs))))
+         if ((code == ADDR_EXPR
+              /* Handle pointer conversions on invariant addresses
+                 as well, as this is valid gimple.  */
+              || (CONVERT_EXPR_CODE_P (code)
+                  && TREE_CODE (rhs) == ADDR_EXPR
+                  && POINTER_TYPE_P (TREE_TYPE (lhs))))
+             && TREE_CODE (TREE_OPERAND (rhs, 0)) != TARGET_MEM_REF)
            {
              tree base = get_base_address (TREE_OPERAND (rhs, 0));
              if ((!base
                   || !DECL_P (base)
                   || decl_address_invariant_p (base))
-                 && TREE_CODE (base) != TARGET_MEM_REF
                  && !stmt_references_abnormal_ssa_name (stmt)
                  && forward_propagate_addr_expr (lhs, rhs, true))
                {
-- 
2.12.3

Reply via email to