mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-26 22:05:16 +08:00
re PR middle-end/66251 (ICE in vect_get_vec_def_for_operand, at tree-vect-stmts.c:1484)
PR middle-end/66251 * tree-vect-stmts.c (vect_model_store_cost): Handled strided group stores. (vect_create_vectorized_demotion_stmts): Always set STMT_VINFO_VEC_STMT, also with SLP. (vectorizable_store): Handle strided group stores. testsuite/: PR middle-end/66251 * gcc.dg/vect/pr66251.c: New test. From-SVN: r223704
This commit is contained in:
parent
dd1bdce418
commit
cee62feed1
@ -1,3 +1,13 @@
|
||||
2015-05-26 Michael Matz <matz@suse.de>
|
||||
|
||||
PR middle-end/66251
|
||||
|
||||
* tree-vect-stmts.c (vect_model_store_cost): Handled strided group
|
||||
stores.
|
||||
(vect_create_vectorized_demotion_stmts): Always set
|
||||
STMT_VINFO_VEC_STMT, also with SLP.
|
||||
(vectorizable_store): Handle strided group stores.
|
||||
|
||||
2015-05-26 Venkataramanan Kumar <venkataramanan.kumar@amd.com>
|
||||
|
||||
PR target/66049
|
||||
|
@ -1,3 +1,8 @@
|
||||
2015-05-26 Michael Matz <matz@suse.de>
|
||||
|
||||
PR middle-end/66251
|
||||
* gcc.dg/vect/pr66251.c: New test.
|
||||
|
||||
2015-05-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/66142
|
||||
|
79
gcc/testsuite/gcc.dg/vect/pr66251.c
Normal file
79
gcc/testsuite/gcc.dg/vect/pr66251.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* { dg-require-effective-target vect_int } */
|
||||
/* { dg-require-effective-target vect_double } */
|
||||
/* { dg-require-effective-target vect_floatint_cvt } */
|
||||
/* { dg-require-effective-target vect_intfloat_cvt } */
|
||||
/* { dg-require-effective-target vect_pack_trunc } */
|
||||
/* { dg-require-effective-target vect_unpack } */
|
||||
/* { dg-require-effective-target vect_hw_misalign } */
|
||||
|
||||
#include "tree-vect.h"
|
||||
|
||||
void __attribute__((noinline,noclone))
|
||||
test1(_Complex double *a, _Complex int *b, int stride, int n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
a[i*stride] = b[i*stride];
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((noinline,noclone))
|
||||
test2(_Complex int *a, _Complex double *b, int stride, int n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
a[i*stride] = b[i*stride];
|
||||
}
|
||||
}
|
||||
|
||||
_Complex int ia[256];
|
||||
_Complex double da[256];
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int main ()
|
||||
{
|
||||
int i;
|
||||
int stride;
|
||||
|
||||
check_vect ();
|
||||
|
||||
for (stride = 1; stride < 15; stride++)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
__real__ ia[i] = (i + stride) % 19;
|
||||
__imag__ ia[i] = (i + stride) % 23;
|
||||
__asm__ volatile ("");
|
||||
}
|
||||
|
||||
test1(da, ia, stride, 256/stride);
|
||||
|
||||
for (i = 0; i < 256/stride; i++)
|
||||
{
|
||||
if (da[i*stride] != ia[i*stride])
|
||||
abort ();
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
__real__ da[i] = (i + stride + 1) % 29;
|
||||
__imag__ da[i] = (i + stride + 1) % 31;
|
||||
__asm__ volatile ("");
|
||||
}
|
||||
|
||||
test2(ia, da, stride, 256/stride);
|
||||
|
||||
for (i = 0; i < 256/stride; i++)
|
||||
{
|
||||
if (da[i*stride] != ia[i*stride])
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vect" } } */
|
@ -1000,7 +1000,8 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
|
||||
equivalent to the cost of GROUP_SIZE separate stores. If a grouped
|
||||
access is instead being provided by a permute-and-store operation,
|
||||
include the cost of the permutes. */
|
||||
if (!store_lanes_p && group_size > 1)
|
||||
if (!store_lanes_p && group_size > 1
|
||||
&& !STMT_VINFO_STRIDED_P (stmt_info))
|
||||
{
|
||||
/* Uses a high and low interleave or shuffle operations for each
|
||||
needed permute. */
|
||||
@ -1014,21 +1015,24 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
|
||||
group_size);
|
||||
}
|
||||
|
||||
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
|
||||
/* Costs of the stores. */
|
||||
if (STMT_VINFO_STRIDED_P (stmt_info))
|
||||
if (STMT_VINFO_STRIDED_P (stmt_info)
|
||||
&& !STMT_VINFO_GROUPED_ACCESS (stmt_info))
|
||||
{
|
||||
/* N scalar stores plus extracting the elements. */
|
||||
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
|
||||
inside_cost += record_stmt_cost (body_cost_vec,
|
||||
ncopies * TYPE_VECTOR_SUBPARTS (vectype),
|
||||
scalar_store, stmt_info, 0, vect_body);
|
||||
inside_cost += record_stmt_cost (body_cost_vec,
|
||||
ncopies * TYPE_VECTOR_SUBPARTS (vectype),
|
||||
vec_to_scalar, stmt_info, 0, vect_body);
|
||||
}
|
||||
else
|
||||
vect_get_store_cost (first_dr, ncopies, &inside_cost, body_cost_vec);
|
||||
|
||||
if (STMT_VINFO_STRIDED_P (stmt_info))
|
||||
inside_cost += record_stmt_cost (body_cost_vec,
|
||||
ncopies * TYPE_VECTOR_SUBPARTS (vectype),
|
||||
vec_to_scalar, stmt_info, 0, vect_body);
|
||||
|
||||
if (dump_enabled_p ())
|
||||
dump_printf_loc (MSG_NOTE, vect_location,
|
||||
"vect_model_store_cost: inside_cost = %d, "
|
||||
@ -3377,15 +3381,13 @@ vect_create_vectorized_demotion_stmts (vec<tree> *vec_oprnds,
|
||||
(or in STMT_VINFO_RELATED_STMT chain). */
|
||||
if (slp_node)
|
||||
SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
|
||||
else
|
||||
{
|
||||
if (!*prev_stmt_info)
|
||||
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
|
||||
else
|
||||
STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt;
|
||||
|
||||
*prev_stmt_info = vinfo_for_stmt (new_stmt);
|
||||
}
|
||||
if (!*prev_stmt_info)
|
||||
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
|
||||
else
|
||||
STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt;
|
||||
|
||||
*prev_stmt_info = vinfo_for_stmt (new_stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5155,15 +5157,27 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||
{
|
||||
grouped_store = true;
|
||||
first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
|
||||
if (!slp && !PURE_SLP_STMT (stmt_info))
|
||||
group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
|
||||
if (!slp
|
||||
&& !PURE_SLP_STMT (stmt_info)
|
||||
&& !STMT_VINFO_STRIDED_P (stmt_info))
|
||||
{
|
||||
group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
|
||||
if (vect_store_lanes_supported (vectype, group_size))
|
||||
store_lanes_p = true;
|
||||
else if (!vect_grouped_store_supported (vectype, group_size))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (STMT_VINFO_STRIDED_P (stmt_info)
|
||||
&& (slp || PURE_SLP_STMT (stmt_info))
|
||||
&& (group_size > nunits
|
||||
|| nunits % group_size != 0))
|
||||
{
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"unhandled strided group store\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (first_stmt == stmt)
|
||||
{
|
||||
/* STMT is the leader of the group. Check the operands of all the
|
||||
@ -5286,10 +5300,23 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||
...
|
||||
*/
|
||||
|
||||
unsigned nstores = nunits;
|
||||
tree ltype = elem_type;
|
||||
if (slp)
|
||||
{
|
||||
nstores = nunits / group_size;
|
||||
if (group_size < nunits)
|
||||
ltype = build_vector_type (elem_type, group_size);
|
||||
else
|
||||
ltype = vectype;
|
||||
ltype = build_aligned_type (ltype, TYPE_ALIGN (elem_type));
|
||||
ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
|
||||
}
|
||||
|
||||
ivstep = stride_step;
|
||||
ivstep = fold_build2 (MULT_EXPR, TREE_TYPE (ivstep), ivstep,
|
||||
build_int_cst (TREE_TYPE (ivstep),
|
||||
ncopies * nunits));
|
||||
ncopies * nstores));
|
||||
|
||||
standard_iv_increment_position (loop, &incr_gsi, &insert_after);
|
||||
|
||||
@ -5315,22 +5342,22 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||
else
|
||||
vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
|
||||
|
||||
for (i = 0; i < nunits; i++)
|
||||
for (i = 0; i < nstores; i++)
|
||||
{
|
||||
tree newref, newoff;
|
||||
gimple incr, assign;
|
||||
tree size = TYPE_SIZE (elem_type);
|
||||
tree size = TYPE_SIZE (ltype);
|
||||
/* Extract the i'th component. */
|
||||
tree pos = fold_build2 (MULT_EXPR, bitsizetype, bitsize_int (i),
|
||||
size);
|
||||
tree elem = fold_build3 (BIT_FIELD_REF, elem_type, vec_oprnd,
|
||||
tree elem = fold_build3 (BIT_FIELD_REF, ltype, vec_oprnd,
|
||||
size, pos);
|
||||
|
||||
elem = force_gimple_operand_gsi (gsi, elem, true,
|
||||
NULL_TREE, true,
|
||||
GSI_SAME_STMT);
|
||||
|
||||
newref = build2 (MEM_REF, TREE_TYPE (vectype),
|
||||
newref = build2 (MEM_REF, ltype,
|
||||
running_off, alias_off);
|
||||
|
||||
/* And store it to *running_off. */
|
||||
|
Loading…
Reference in New Issue
Block a user