mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 11:00:41 +08:00
tree-optimization/97706 - handle PHIs in pattern recog mask precison
This adds handling of PHIs to mask precision compute which is eventually needed to detect a bool pattern when the def chain contains such a PHI node. 2020-11-06 Richard Biener <rguenther@suse.de> PR tree-optimization/97706 * tree-vect-patterns.c (possible_vector_mask_operation_p): PHIs are possible mask operations. (vect_determine_mask_precision): Handle PHIs. (vect_determine_precisions): Walk PHIs in BB analysis. * gcc.dg/vect/bb-slp-pr97706.c: New testcase.
This commit is contained in:
parent
1db815f4f3
commit
22175d0dc6
61
gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c
Normal file
61
gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
_Bool arr[16];
|
||||
void bar();
|
||||
void foo(int n, char *p)
|
||||
{
|
||||
_Bool b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
|
||||
do
|
||||
{
|
||||
b0 = p[0] != 0;
|
||||
b1 = p[1] != 0;
|
||||
b2 = p[2] != 0;
|
||||
b3 = p[3] != 0;
|
||||
b4 = p[4] != 0;
|
||||
b5 = p[5] != 0;
|
||||
b6 = p[6] != 0;
|
||||
b7 = p[7] != 0;
|
||||
b8 = p[8] != 0;
|
||||
b9 = p[9] != 0;
|
||||
b10 = p[10] != 0;
|
||||
b11 = p[11] != 0;
|
||||
b12 = p[12] != 0;
|
||||
b13 = p[13] != 0;
|
||||
b14 = p[14] != 0;
|
||||
b15 = p[15] != 0;
|
||||
arr[0] = b0;
|
||||
arr[1] = b1;
|
||||
arr[2] = b2;
|
||||
arr[3] = b3;
|
||||
arr[4] = b4;
|
||||
arr[5] = b5;
|
||||
arr[6] = b6;
|
||||
arr[7] = b7;
|
||||
arr[8] = b8;
|
||||
arr[9] = b9;
|
||||
arr[10] = b10;
|
||||
arr[11] = b11;
|
||||
arr[12] = b12;
|
||||
arr[13] = b13;
|
||||
arr[14] = b14;
|
||||
arr[15] = b15;
|
||||
bar ();
|
||||
}
|
||||
while (--n);
|
||||
arr[0] = b0;
|
||||
arr[1] = b1;
|
||||
arr[2] = b2;
|
||||
arr[3] = b3;
|
||||
arr[4] = b4;
|
||||
arr[5] = b5;
|
||||
arr[6] = b6;
|
||||
arr[7] = b7;
|
||||
arr[8] = b8;
|
||||
arr[9] = b9;
|
||||
arr[10] = b10;
|
||||
arr[11] = b11;
|
||||
arr[12] = b12;
|
||||
arr[13] = b13;
|
||||
arr[14] = b14;
|
||||
arr[15] = b15;
|
||||
}
|
@ -5007,6 +5007,8 @@ possible_vector_mask_operation_p (stmt_vec_info stmt_info)
|
||||
return TREE_CODE_CLASS (rhs_code) == tcc_comparison;
|
||||
}
|
||||
}
|
||||
else if (is_a <gphi *> (stmt_info->stmt))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5049,41 +5051,63 @@ vect_determine_mask_precision (vec_info *vinfo, stmt_vec_info stmt_info)
|
||||
The number of operations are equal, but M16 would have given
|
||||
a shorter dependency chain and allowed more ILP. */
|
||||
unsigned int precision = ~0U;
|
||||
gassign *assign = as_a <gassign *> (stmt_info->stmt);
|
||||
unsigned int nops = gimple_num_ops (assign);
|
||||
for (unsigned int i = 1; i < nops; ++i)
|
||||
if (gassign *assign = dyn_cast <gassign *> (stmt_info->stmt))
|
||||
{
|
||||
tree rhs = gimple_op (assign, i);
|
||||
if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs)))
|
||||
continue;
|
||||
|
||||
stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
|
||||
if (!def_stmt_info)
|
||||
/* Don't let external or constant operands influence the choice.
|
||||
We can convert them to whichever vector type we pick. */
|
||||
continue;
|
||||
|
||||
if (def_stmt_info->mask_precision)
|
||||
unsigned int nops = gimple_num_ops (assign);
|
||||
for (unsigned int i = 1; i < nops; ++i)
|
||||
{
|
||||
if (precision > def_stmt_info->mask_precision)
|
||||
precision = def_stmt_info->mask_precision;
|
||||
tree rhs = gimple_op (assign, i);
|
||||
if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (rhs)))
|
||||
continue;
|
||||
|
||||
stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
|
||||
if (!def_stmt_info)
|
||||
/* Don't let external or constant operands influence the choice.
|
||||
We can convert them to whichever vector type we pick. */
|
||||
continue;
|
||||
|
||||
if (def_stmt_info->mask_precision)
|
||||
{
|
||||
if (precision > def_stmt_info->mask_precision)
|
||||
precision = def_stmt_info->mask_precision;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the statement compares two values that shouldn't use vector masks,
|
||||
try comparing the values as normal scalars instead. */
|
||||
tree_code rhs_code = gimple_assign_rhs_code (assign);
|
||||
if (precision == ~0U
|
||||
&& TREE_CODE_CLASS (rhs_code) == tcc_comparison)
|
||||
{
|
||||
tree rhs1_type = TREE_TYPE (gimple_assign_rhs1 (assign));
|
||||
scalar_mode mode;
|
||||
tree vectype, mask_type;
|
||||
if (is_a <scalar_mode> (TYPE_MODE (rhs1_type), &mode)
|
||||
&& (vectype = get_vectype_for_scalar_type (vinfo, rhs1_type))
|
||||
&& (mask_type = get_mask_type_for_scalar_type (vinfo, rhs1_type))
|
||||
&& expand_vec_cmp_expr_p (vectype, mask_type, rhs_code))
|
||||
precision = GET_MODE_BITSIZE (mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the statement compares two values that shouldn't use vector masks,
|
||||
try comparing the values as normal scalars instead. */
|
||||
tree_code rhs_code = gimple_assign_rhs_code (assign);
|
||||
if (precision == ~0U
|
||||
&& TREE_CODE_CLASS (rhs_code) == tcc_comparison)
|
||||
else
|
||||
{
|
||||
tree rhs1_type = TREE_TYPE (gimple_assign_rhs1 (assign));
|
||||
scalar_mode mode;
|
||||
tree vectype, mask_type;
|
||||
if (is_a <scalar_mode> (TYPE_MODE (rhs1_type), &mode)
|
||||
&& (vectype = get_vectype_for_scalar_type (vinfo, rhs1_type))
|
||||
&& (mask_type = get_mask_type_for_scalar_type (vinfo, rhs1_type))
|
||||
&& expand_vec_cmp_expr_p (vectype, mask_type, rhs_code))
|
||||
precision = GET_MODE_BITSIZE (mode);
|
||||
gphi *phi = as_a <gphi *> (stmt_info->stmt);
|
||||
for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
|
||||
{
|
||||
tree rhs = gimple_phi_arg_def (phi, i);
|
||||
|
||||
stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs);
|
||||
if (!def_stmt_info)
|
||||
/* Don't let external or constant operands influence the choice.
|
||||
We can convert them to whichever vector type we pick. */
|
||||
continue;
|
||||
|
||||
if (def_stmt_info->mask_precision)
|
||||
{
|
||||
if (precision > def_stmt_info->mask_precision)
|
||||
precision = def_stmt_info->mask_precision;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dump_enabled_p ())
|
||||
@ -5164,15 +5188,30 @@ vect_determine_precisions (vec_info *vinfo)
|
||||
if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
|
||||
vect_determine_mask_precision (vinfo, stmt_info);
|
||||
}
|
||||
for (auto gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
{
|
||||
stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
|
||||
if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
|
||||
vect_determine_mask_precision (vinfo, stmt_info);
|
||||
}
|
||||
}
|
||||
for (int i = bb_vinfo->bbs.length () - 1; i != -1; --i)
|
||||
for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
|
||||
!gsi_end_p (gsi); gsi_prev (&gsi))
|
||||
{
|
||||
stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
|
||||
if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
|
||||
vect_determine_stmt_precisions (vinfo, stmt_info);
|
||||
}
|
||||
{
|
||||
for (gimple_stmt_iterator gsi = gsi_last_bb (bb_vinfo->bbs[i]);
|
||||
!gsi_end_p (gsi); gsi_prev (&gsi))
|
||||
{
|
||||
stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (gsi));
|
||||
if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
|
||||
vect_determine_stmt_precisions (vinfo, stmt_info);
|
||||
}
|
||||
for (auto gsi = gsi_start_phis (bb_vinfo->bbs[i]);
|
||||
!gsi_end_p (gsi); gsi_next (&gsi))
|
||||
{
|
||||
stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi.phi ());
|
||||
if (stmt_info && STMT_VINFO_VECTORIZABLE (stmt_info))
|
||||
vect_determine_stmt_precisions (vinfo, stmt_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user