From patchwork Thu Oct 8 15:15:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 527776 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DA794140E5A for ; Fri, 9 Oct 2015 02:16:32 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=fG9xFSXb; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=h0fczP9w9VZN+xvG1S0kHEvhEpQhwxhzu7Y2y4Albvy/kL++j0crr 4qHPQdqj77mtMfiJxDQAccolmbkTeBidhxYIfcl5ziMulhp6XtULwAlH3TD+fLle iyfcKWYn54yYEfmXLThAgn2DvSsQ2+dUyBMGlBEN1f+s4uQDvy1yCU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=af3OtZqYQfagzuW0TJRbhBdfRe4=; b=fG9xFSXblucJrPlW/B1y FYNkoHI5wLRvUpwI8DxCKstHrlUgNF2w8XxfLpzEAg3Yjvn8lJzjWDy3QcGXM47a BhyYmc7jkoHPz2YlSAENH6asa80QOXFHs5PP1xxASHJrBzUAfMbo0Ek1Z8M1+2HI hSYdqzFZBjL712dcCtxYLjI= Received: (qmail 37371 invoked by alias); 8 Oct 2015 15:16:23 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 37361 invoked by uid 89); 8 Oct 2015 15:16:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wi0-f169.google.com Received: from mail-wi0-f169.google.com (HELO mail-wi0-f169.google.com) (209.85.212.169) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 08 Oct 2015 15:16:20 +0000 Received: by wicfx3 with SMTP id fx3so30064055wic.0 for ; Thu, 08 Oct 2015 08:16:18 -0700 (PDT) X-Received: by 10.194.118.5 with SMTP id ki5mr8344982wjb.94.1444317377880; Thu, 08 Oct 2015 08:16:17 -0700 (PDT) Received: from msticlxl57.ims.intel.com (jfdmzpr02-ext.jf.intel.com. [134.134.137.71]) by smtp.gmail.com with ESMTPSA id jd7sm24936199wjb.19.2015.10.08.08.16.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Oct 2015 08:16:17 -0700 (PDT) Date: Thu, 8 Oct 2015 18:15:57 +0300 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [vec-cmp, patch 5/6] Disable bool patterns when possible Message-ID: <20151008151557.GF63757@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi, This patch disables transformation of boolean computations into integer ones in case target supports vector comparison. Pattern still applies to transform resulting boolean value into integer or avoid COND_EXPR with SSA_NAME as condition. Thanks, Ilya --- 2015-10-08 Ilya Enkovich * tree-vect-patterns.c (check_bool_pattern): Check fails if we can vectorize comparison directly. (search_type_for_mask): New. (vect_recog_bool_pattern): Support cases when bool pattern check fails. diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 830801a..e3be3d1 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -2951,7 +2951,7 @@ check_bool_pattern (tree var, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) default: if (TREE_CODE_CLASS (rhs_code) == tcc_comparison) { - tree vecitype, comp_vectype; + tree vecitype, comp_vectype, mask_type; /* If the comparison can throw, then is_gimple_condexpr will be false and we can't make a COND_EXPR/VEC_COND_EXPR out of it. */ @@ -2962,6 +2962,11 @@ check_bool_pattern (tree var, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) if (comp_vectype == NULL_TREE) return false; + mask_type = get_mask_type_for_scalar_type (TREE_TYPE (rhs1)); + if (mask_type + && expand_vec_cmp_expr_p (comp_vectype, mask_type)) + return false; + if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE) { machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1)); @@ -3186,6 +3191,75 @@ adjust_bool_pattern (tree var, tree out_type, tree trueval, } +/* Try to determine a proper type for converting bool VAR + into an integer value. The type is chosen so that + conversion has the same number of elements as a mask + producer. */ + +static tree +search_type_for_mask (tree var, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) +{ + gimple *def_stmt; + enum vect_def_type dt; + tree def, rhs1; + enum tree_code rhs_code; + tree res = NULL; + + if (TREE_CODE (var) != SSA_NAME) + return NULL; + + if ((TYPE_PRECISION (TREE_TYPE (var)) != 1 + || !TYPE_UNSIGNED (TREE_TYPE (var))) + && TREE_CODE (TREE_TYPE (var)) != BOOLEAN_TYPE) + return NULL; + + if (!vect_is_simple_use (var, NULL, loop_vinfo, bb_vinfo, &def_stmt, &def, + &dt)) + return NULL; + + if (dt != vect_internal_def) + return NULL; + + if (!is_gimple_assign (def_stmt)) + return NULL; + + rhs_code = gimple_assign_rhs_code (def_stmt); + rhs1 = gimple_assign_rhs1 (def_stmt); + + switch (rhs_code) + { + case SSA_NAME: + case BIT_NOT_EXPR: + CASE_CONVERT: + res = search_type_for_mask (rhs1, loop_vinfo, bb_vinfo); + break; + + case BIT_AND_EXPR: + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + if (!(res = search_type_for_mask (rhs1, loop_vinfo, bb_vinfo))) + res = search_type_for_mask (gimple_assign_rhs2 (def_stmt), + loop_vinfo, bb_vinfo); + break; + + default: + if (TREE_CODE_CLASS (rhs_code) == tcc_comparison) + { + if (TREE_CODE (TREE_TYPE (rhs1)) != INTEGER_TYPE + || !TYPE_UNSIGNED (TREE_TYPE (rhs1))) + { + machine_mode mode = TYPE_MODE (TREE_TYPE (rhs1)); + res = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode), 1); + } + else + res = TREE_TYPE (rhs1); + } + } + + return res; +} + + /* Function vect_recog_bool_pattern Try to find pattern like following: @@ -3243,6 +3317,7 @@ vect_recog_bool_pattern (vec *stmts, tree *type_in, enum tree_code rhs_code; tree var, lhs, rhs, vectype; stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); + stmt_vec_info new_stmt_info; loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo); gimple *pattern_stmt; @@ -3268,16 +3343,53 @@ vect_recog_bool_pattern (vec *stmts, tree *type_in, if (vectype == NULL_TREE) return NULL; - if (!check_bool_pattern (var, loop_vinfo, bb_vinfo)) - return NULL; - - rhs = adjust_bool_pattern (var, TREE_TYPE (lhs), NULL_TREE, stmts); - lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); - if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) - pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs); + if (check_bool_pattern (var, loop_vinfo, bb_vinfo)) + { + rhs = adjust_bool_pattern (var, TREE_TYPE (lhs), NULL_TREE, stmts); + lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); + if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) + pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs); + else + pattern_stmt + = gimple_build_assign (lhs, NOP_EXPR, rhs); + } else - pattern_stmt - = gimple_build_assign (lhs, NOP_EXPR, rhs); + { + tree type = search_type_for_mask (var, loop_vinfo, bb_vinfo); + tree cst0, cst1, cmp, tmp; + + if (!type) + return NULL; + + /* We may directly use cond with narrowed type to avoid + multiple cond exprs with following result packing and + perform single cond with packed mask intead. In case + of widening we better make cond first and then extract + results. */ + if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (lhs))) + type = TREE_TYPE (lhs); + + cst0 = build_int_cst (type, 0); + cst1 = build_int_cst (type, 1); + tmp = vect_recog_temp_ssa_var (type, NULL); + cmp = build2 (NE_EXPR, boolean_type_node, + var, build_int_cst (TREE_TYPE (var), 0)); + pattern_stmt = gimple_build_assign (tmp, COND_EXPR, cmp, cst1, cst0); + + if (!useless_type_conversion_p (type, TREE_TYPE (lhs))) + { + tree new_vectype = get_vectype_for_scalar_type (type); + new_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo, + bb_vinfo); + set_vinfo_for_stmt (pattern_stmt, new_stmt_info); + STMT_VINFO_VECTYPE (new_stmt_info) = new_vectype; + new_pattern_def_seq (stmt_vinfo, pattern_stmt); + + lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); + pattern_stmt = gimple_build_assign (lhs, CONVERT_EXPR, tmp); + } + } + *type_out = vectype; *type_in = vectype; stmts->safe_push (last_stmt); @@ -3306,15 +3418,19 @@ vect_recog_bool_pattern (vec *stmts, tree *type_in, if (get_vectype_for_scalar_type (type) == NULL_TREE) return NULL; - if (!check_bool_pattern (var, loop_vinfo, bb_vinfo)) - return NULL; + if (check_bool_pattern (var, loop_vinfo, bb_vinfo)) + { + rhs = adjust_bool_pattern (var, type, NULL_TREE, stmts); + rhs = build2 (NE_EXPR, boolean_type_node, + rhs, build_int_cst (type, 0)); + } + else + rhs = build2 (NE_EXPR, boolean_type_node, + var, build_int_cst (TREE_TYPE (var), 0)), - rhs = adjust_bool_pattern (var, type, NULL_TREE, stmts); lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); pattern_stmt - = gimple_build_assign (lhs, COND_EXPR, - build2 (NE_EXPR, boolean_type_node, - rhs, build_int_cst (type, 0)), + = gimple_build_assign (lhs, COND_EXPR, rhs, gimple_assign_rhs2 (last_stmt), gimple_assign_rhs3 (last_stmt)); *type_out = vectype; @@ -3334,16 +3450,44 @@ vect_recog_bool_pattern (vec *stmts, tree *type_in, gcc_assert (vectype != NULL_TREE); if (!VECTOR_MODE_P (TYPE_MODE (vectype))) return NULL; - if (!check_bool_pattern (var, loop_vinfo, bb_vinfo)) - return NULL; - rhs = adjust_bool_pattern (var, TREE_TYPE (vectype), NULL_TREE, stmts); + if (check_bool_pattern (var, loop_vinfo, bb_vinfo)) + rhs = adjust_bool_pattern (var, TREE_TYPE (vectype), + NULL_TREE, stmts); + else + { + tree type = search_type_for_mask (var, loop_vinfo, bb_vinfo); + tree cst0, cst1, cmp, new_vectype; + + if (!type) + return NULL; + + if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (vectype))) + type = TREE_TYPE (vectype); + + cst0 = build_int_cst (type, 0); + cst1 = build_int_cst (type, 1); + new_vectype = get_vectype_for_scalar_type (type); + + rhs = vect_recog_temp_ssa_var (type, NULL); + cmp = build2 (NE_EXPR, boolean_type_node, + var, build_int_cst (TREE_TYPE (var), 0)); + pattern_stmt = gimple_build_assign (rhs, COND_EXPR, + cmp, cst1, cst0); + + pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo, + bb_vinfo); + set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); + STMT_VINFO_VECTYPE (pattern_stmt_info) = new_vectype; + append_pattern_def_seq (stmt_vinfo, pattern_stmt); + } + lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vectype), lhs); if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) { tree rhs2 = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); gimple *cast_stmt = gimple_build_assign (rhs2, NOP_EXPR, rhs); - new_pattern_def_seq (stmt_vinfo, cast_stmt); + append_pattern_def_seq (stmt_vinfo, cast_stmt); rhs = rhs2; } pattern_stmt = gimple_build_assign (lhs, SSA_NAME, rhs);