Commit 891ad31c by Richard Biener Committed by Richard Biener

re PR tree-optimization/61171 (vectorization fails for a reduction in presence of subtraction)

2017-07-20  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/61171
	* tree-vectorizer.h (slp_instance): Add reduc_phis member.
	(vect_analyze_stmt): Add slp instance parameter.
	(vectorizable_reduction): Likewise.
	* tree-vect-loop.c (vect_analyze_loop_operations): Adjust.
	(vect_is_simple_reduction): Deal with chains not detected
	as SLP reduction chain, specifically not properly associated
	chains containing a mix of plus/minus.
	(get_reduction_op): Remove.
	(get_initial_defs_for_reduction): Simplify, pass in whether
	this is a reduction chain, pass in the SLP node for the PHIs.
	(vect_create_epilog_for_reduction): Get the SLP instance as
	arg and adjust.
	(vectorizable_reduction): Get the SLP instance as arg.
	During analysis remember the SLP node with the PHIs in the
	instance.  Simplify getting at the vectorized reduction PHIs.
	* tree-vect-slp.c (vect_slp_analyze_node_operations): Pass
	through SLP instance.
	(vect_slp_analyze_operations): Likewise.
	* tree-vect-stms.c (vect_analyze_stmt): Likewise.
	(vect_transform_stmt): Likewise.

	* g++.dg/vect/pr61171.cc: New testcase.
	* gfortran.dg/vect/pr61171.f: Likewise.
	* gcc.dg/vect/vect-reduc-11.c: Likewise.

From-SVN: r250382
parent f971b281
2017-07-20 Richard Biener <rguenther@suse.de>
PR tree-optimization/61171
* tree-vectorizer.h (slp_instance): Add reduc_phis member.
(vect_analyze_stmt): Add slp instance parameter.
(vectorizable_reduction): Likewise.
* tree-vect-loop.c (vect_analyze_loop_operations): Adjust.
(vect_is_simple_reduction): Deal with chains not detected
as SLP reduction chain, specifically not properly associated
chains containing a mix of plus/minus.
(get_reduction_op): Remove.
(get_initial_defs_for_reduction): Simplify, pass in whether
this is a reduction chain, pass in the SLP node for the PHIs.
(vect_create_epilog_for_reduction): Get the SLP instance as
arg and adjust.
(vectorizable_reduction): Get the SLP instance as arg.
During analysis remember the SLP node with the PHIs in the
instance. Simplify getting at the vectorized reduction PHIs.
* tree-vect-slp.c (vect_slp_analyze_node_operations): Pass
through SLP instance.
(vect_slp_analyze_operations): Likewise.
* tree-vect-stms.c (vect_analyze_stmt): Likewise.
(vect_transform_stmt): Likewise.
2017-07-20 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/81489
......
2017-07-20 Richard Biener <rguenther@suse.de>
PR tree-optimization/61171
* g++.dg/vect/pr61171.cc: New testcase.
* gfortran.dg/vect/pr61171.f: Likewise.
* gcc.dg/vect/vect-reduc-11.c: Likewise.
2017-07-20 Richard Biener <rguenther@suse.de>
* gcc.dg/vect/slp-43.c: Increase loop count to enable vectorization
with V64QImode.
* gcc.dg/vect/slp-45.c: Likewise.
......
// { dg-do compile }
// { dg-require-effective-target vect_float }
// { dg-additional-options "-ffast-math" }
float px[1024];
float xx, vv;
unsigned int N=1024;
void ok() {
for (unsigned j=0U; j<N; ++j) {
float ax = px[j]-xx;
vv-=ax;
}
}
void noOk() {
for (unsigned j=0U; j<N; ++j) {
float ax = xx-px[j];
vv+=ax;
}
}
// { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } }
/* { dg-do run } */
/* { dg-require-effective-target vect_int } */
#include "tree-vect.h"
int x[1024], y[1024], z[1024];
int __attribute__((noinline,noclone))
foo (int n)
{
int sum = 0;
/* Can vectorize this. */
for (int i = 0; i < n; ++i)
sum = (y[i] - (x[i] - sum));
return sum;
}
int __attribute__((noinline,noclone))
bar (int n)
{
int sum = 0;
/* Cannot vectorize this, sum is negated. */
for (int i = 0; i < n; ++i)
sum = z[i] - (y[i] - (x[i] - sum));
return sum;
}
int
main()
{
check_vect ();
for (int i = 0; i < 1024; ++i)
{
x[i] = i;
y[i] = i + 1;
z[i] = 0;
__asm__ volatile ("" : : : "memory");
}
if (foo (1024) != 1024)
__builtin_abort ();
if (bar (1023) != -1 || bar (1024) != 0)
__builtin_abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
! { dg-do compile }
! { dg-additional-options "-Ofast" }
SUBROUTINE GAUBON(NV,PTS,PP)
IMPLICIT DOUBLE PRECISION(A-H,O-Z)
PARAMETER (MXSP=250)
DIMENSION PTS(3,10),PP(3)
COMMON /PCMPLY/ XE(MXSP),YE(MXSP),ZE(MXSP)
DATA PI/3.141592653589793D+00/
DATA ZERO/0.0D+00/
DO I = 1, NV
PP(1) = PP(1) + (PTS(1,I)-XE(NS))
PP(2) = PP(2) + (PTS(2,I)-YE(NS))
PP(3) = PP(3) + (PTS(3,I)-ZE(NS))
ENDDO
END
......@@ -2439,7 +2439,7 @@ destroy_bb_vec_info (bb_vec_info bb_vinfo)
the subtree. Return TRUE if the operations are supported. */
static bool
vect_slp_analyze_node_operations (slp_tree node)
vect_slp_analyze_node_operations (slp_tree node, slp_instance node_instance)
{
bool dummy;
int i, j;
......@@ -2450,7 +2450,7 @@ vect_slp_analyze_node_operations (slp_tree node)
return true;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
if (!vect_slp_analyze_node_operations (child))
if (!vect_slp_analyze_node_operations (child, node_instance))
return false;
stmt = SLP_TREE_SCALAR_STMTS (node)[0];
......@@ -2507,7 +2507,7 @@ vect_slp_analyze_node_operations (slp_tree node)
if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (child)[0]))
= SLP_TREE_DEF_TYPE (child);
bool res = vect_analyze_stmt (stmt, &dummy, node);
bool res = vect_analyze_stmt (stmt, &dummy, node, node_instance);
/* Restore def-types. */
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
if (SLP_TREE_DEF_TYPE (child) != vect_internal_def)
......@@ -2535,7 +2535,8 @@ vect_slp_analyze_operations (vec<slp_instance> slp_instances, void *data)
for (i = 0; slp_instances.iterate (i, &instance); )
{
if (!vect_slp_analyze_node_operations (SLP_INSTANCE_TREE (instance)))
if (!vect_slp_analyze_node_operations (SLP_INSTANCE_TREE (instance),
instance))
{
dump_printf_loc (MSG_NOTE, vect_location,
"removing SLP instance operations starting from: ");
......
......@@ -8397,7 +8397,8 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
/* Make sure the statement is vectorizable. */
bool
vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node)
vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node,
slp_instance node_instance)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
......@@ -8476,7 +8477,8 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node)
dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
if (!vect_analyze_stmt (pattern_stmt, need_to_vectorize, node))
if (!vect_analyze_stmt (pattern_stmt, need_to_vectorize, node,
node_instance))
return false;
}
......@@ -8501,7 +8503,7 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node)
}
if (!vect_analyze_stmt (pattern_def_stmt,
need_to_vectorize, node))
need_to_vectorize, node, node_instance))
return false;
}
}
......@@ -8561,7 +8563,7 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node)
|| vectorizable_load (stmt, NULL, NULL, node, NULL)
|| vectorizable_call (stmt, NULL, NULL, node)
|| vectorizable_store (stmt, NULL, NULL, node)
|| vectorizable_reduction (stmt, NULL, NULL, node)
|| vectorizable_reduction (stmt, NULL, NULL, node, node_instance)
|| vectorizable_induction (stmt, NULL, NULL, node)
|| vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)
|| vectorizable_comparison (stmt, NULL, NULL, NULL, node));
......@@ -8711,7 +8713,8 @@ vect_transform_stmt (gimple *stmt, gimple_stmt_iterator *gsi,
break;
case reduc_vec_info_type:
done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node);
done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node,
slp_node_instance);
gcc_assert (done);
break;
......
......@@ -127,6 +127,9 @@ typedef struct _slp_instance {
/* The group of nodes that contain loads of this SLP instance. */
vec<slp_tree> loads;
/* The SLP node containing the reduction PHIs. */
slp_tree reduc_phis;
} *slp_instance;
......@@ -1107,7 +1110,7 @@ extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);
extern bool vect_transform_stmt (gimple *, gimple_stmt_iterator *,
bool *, slp_tree, slp_instance);
extern void vect_remove_stores (gimple *);
extern bool vect_analyze_stmt (gimple *, bool *, slp_tree);
extern bool vect_analyze_stmt (gimple *, bool *, slp_tree, slp_instance);
extern bool vectorizable_condition (gimple *, gimple_stmt_iterator *,
gimple **, tree, int, slp_tree);
extern void vect_get_load_cost (struct data_reference *, int, bool,
......@@ -1178,7 +1181,7 @@ extern loop_vec_info vect_analyze_loop_form (struct loop *);
extern bool vectorizable_live_operation (gimple *, gimple_stmt_iterator *,
slp_tree, int, gimple **);
extern bool vectorizable_reduction (gimple *, gimple_stmt_iterator *,
gimple **, slp_tree);
gimple **, slp_tree, slp_instance);
extern bool vectorizable_induction (gimple *, gimple_stmt_iterator *,
gimple **, slp_tree);
extern tree get_initial_def_for_reduction (gimple *, tree, tree *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment