This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR81571
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 27 Jul 2017 15:43:33 +0200 (CEST)
- Subject: [PATCH] Fix PR81571
- Authentication-results: sourceware.org; auth=none
The following fixes PR81571.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2017-07-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/81571
* tree-vect-slp.c (vect_build_slp_tree): Properly verify reduction
PHIs.
* gcc.dg/torture/pr81571.c: New testcase.
Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c (revision 250607)
+++ gcc/tree-vect-slp.c (working copy)
@@ -947,11 +948,27 @@ vect_build_slp_tree (vec_info *vinfo,
the recursion. */
if (gimple_code (stmt) == GIMPLE_PHI)
{
+ vect_def_type def_type = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (stmt));
/* Induction from different IVs is not supported. */
- if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (stmt)) == vect_induction_def)
- FOR_EACH_VEC_ELT (stmts, i, stmt)
- if (stmt != stmts[0])
- return NULL;
+ if (def_type == vect_induction_def)
+ {
+ FOR_EACH_VEC_ELT (stmts, i, stmt)
+ if (stmt != stmts[0])
+ return NULL;
+ }
+ else
+ {
+ /* Else def types have to match. */
+ FOR_EACH_VEC_ELT (stmts, i, stmt)
+ {
+ /* But for reduction chains only check on the first stmt. */
+ if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt))
+ && GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt)
+ continue;
+ if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (stmt)) != def_type)
+ return NULL;
+ }
+ }
node = vect_create_new_slp_node (stmts);
return node;
}
Index: gcc/testsuite/gcc.dg/torture/pr81571.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr81571.c (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr81571.c (working copy)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int a, b, c, d;
+short fn1(int p1, int p2) { return p1; }
+
+int fn2(int p1) {}
+
+int main()
+{
+ for (; c; c++)
+ a |= fn1(1, a) | fn2(b |= d);
+ return 0;
+}