diff options
author | Richard Biener <rguenther@suse.de> | 2020-11-05 12:34:42 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-11-06 15:00:37 +0100 |
commit | 22175d0dc6a89ddd630f19d0f32a2d1ddb046807 (patch) | |
tree | aed64ec1f9738c46975c3ab1d927346e2b4b9bfa /gcc/tree-vect-patterns.c | |
parent | 1db815f4f38be2028ab386b2a5e5e43a88280d21 (diff) | |
download | gcc-22175d0dc6a89ddd630f19d0f32a2d1ddb046807.zip gcc-22175d0dc6a89ddd630f19d0f32a2d1ddb046807.tar.gz gcc-22175d0dc6a89ddd630f19d0f32a2d1ddb046807.tar.bz2 |
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.
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r-- | gcc/tree-vect-patterns.c | 109 |
1 files changed, 74 insertions, 35 deletions
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 47d9fce..eefa7cf 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -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; + unsigned int nops = gimple_num_ops (assign); + for (unsigned int i = 1; i < nops; ++i) + { + 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; + 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 (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) { - if (precision > def_stmt_info->mask_precision) - precision = def_stmt_info->mask_precision; + 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); + } + } } } |