From: Richard Biener Date: Thu, 5 Nov 2020 11:34:42 +0000 (+0100) Subject: tree-optimization/97706 - handle PHIs in pattern recog mask precison X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=22175d0dc6a89ddd630f19d0f32a2d1ddb046807;p=gcc.git 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 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. --- diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c new file mode 100644 index 00000000000..228ae700e8c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr97706.c @@ -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; +} diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 47d9fce594f..eefa7cf6799 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 (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 (stmt_info->stmt); - unsigned int nops = gimple_num_ops (assign); - for (unsigned int i = 1; i < nops; ++i) + if (gassign *assign = dyn_cast (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 (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 (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 (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); + } + } } }