diff mbox series

Fix PR87974

Message ID alpine.LSU.2.20.1811131359420.1827@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR87974 | expand

Commit Message

Richard Biener Nov. 13, 2018, 1:07 p.m. UTC
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  <rguenther@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.
diff mbox series

Patch

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;
+    }
+}