Do not look at constant or external defs in reduction stmts to
determine the reduction PHI vector type.  Those are promoted/demoted
as required.

This is another fragile area, I'll poke around a bit but nevertheless,
bootstrap & regtest queued.

Richard.

2018-11-13  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/87974
        * tree-vect-loop.c (vectorizable_reduction): When computing
        the vectorized reduction PHI vector type ignore constant
        and external defs.

        * g++.dg/opt/pr87974.C: New testcase.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c        (revision 266061)
+++ gcc/tree-vect-loop.c        (working copy)
@@ -6061,13 +6070,17 @@ vectorizable_reduction (stmt_vec_info st
        return true;
 
       gassign *reduc_stmt = as_a <gassign *> (reduc_stmt_info->stmt);
+      code = gimple_assign_rhs_code (reduc_stmt);
       for (unsigned k = 1; k < gimple_num_ops (reduc_stmt); ++k)
        {
          tree op = gimple_op (reduc_stmt, k);
          if (op == phi_result)
            continue;
-         if (k == 1
-             && gimple_assign_rhs_code (reduc_stmt) == COND_EXPR)
+         if (k == 1 && code == COND_EXPR)
+           continue;
+         bool is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt);
+         gcc_assert (is_simple_use);
+         if (dt == vect_constant_def || dt == vect_external_def)
            continue;
          if (!vectype_in
              || (GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (vectype_in)))
Index: gcc/testsuite/g++.dg/opt/pr87974.C
===================================================================
--- gcc/testsuite/g++.dg/opt/pr87974.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr87974.C  (working copy)
@@ -0,0 +1,33 @@
+// { dg-do compile }
+// { dg-options "-O3" }
+
+struct h {
+    typedef int &c;
+};
+class i {
+    struct j {
+       using c = int *;
+    };
+    using as = j::c;
+};
+template <typename> class k {
+public:
+    using as = i::as;
+    h::c operator[](long l) {
+       k<int[]>::as d = 0;
+       return d[l];
+    }
+};
+class : public k<int[]> { } a;
+long c, f;
+void m()
+{
+  for (long b; b <= 6; b++)
+    for (long g; g < b; g++) {
+       unsigned long e = g;
+       c = 0;
+       for (; c < b; c++)
+         f = e >>= 1;
+       a[g] = f;
+    }
+}

Reply via email to