From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28279 invoked by alias); 29 Aug 2011 15:11:49 -0000 Received: (qmail 28267 invoked by uid 22791); 29 Aug 2011 15:11:47 -0000 X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,TW_TM X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 29 Aug 2011 15:11:28 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 59CC28A908; Mon, 29 Aug 2011 17:11:27 +0200 (CEST) Date: Mon, 29 Aug 2011 16:36:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Cc: uros@gcc.gnu.org, rth@redhat.com, artyom.shinkaroff@gmail.com Subject: Re: [PATCH] Change vcond to vcond In-Reply-To: Message-ID: References: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-08/txt/msg02369.txt.bz2 On Mon, 29 Aug 2011, Richard Guenther wrote: > > This patch makes a conversion optab from the direct optabs vcond > and vcondu. This allows to specify different modes for the > actual comparison and the value that is selected. > > All targets but i386 are trivially converted by > s/vcond/vcond/. The i386 port is enhanced > to support a OP b ? c : d as ({ mask = a OP b; (c & mask) | (d & ~mask); > }), constraining it to what the middle-end constrained itself to > (matching number of vector elements in the comparison operands with > the result vector types) would explode patterns too much. > Thus, only a subset of mode combinations will be excercised > (but none at the moment - a followup will fix the vectorizer, > and generic vectors from the C extensions have a patch pending). > > Bootstrapped on x86_64-unknown-linux-gnu, tests are currently > running for {,-m32}. > > Ok if that succeeds? And this is the followup implementing the auto-vectorization part. For i386 I avoided to rewrite the vector comparison insn patterns to allow any result mode by doing a separate conversion emitted from ix86_expand_sse_cmp. Bootstrap and regtest pending on x86_64-unknown-linux-gnu. I'm considering to merge the two patches to avoid the unexcercisable new code. Comments? Ok? Thanks, Richard. 2011-08-29 Richard Guenther PR tree-optimization/27460 * gcc/config/i386/i386.c (ix86_expand_sse_cmp): Use proper mode for the comparison. * tree-vect-stmts.c (vect_is_simple_cond): Return the comparison vector type. (vectorizable_condition): Allow differing types for comparison and result. * gcc.dg/vect/vect-cond-7.c: New testcase. Index: trunk/gcc/config/i386/i386.c =================================================================== *** trunk.orig/gcc/config/i386/i386.c 2011-08-29 16:57:30.000000000 +0200 --- trunk/gcc/config/i386/i386.c 2011-08-29 17:05:32.000000000 +0200 *************** ix86_expand_sse_cmp (rtx dest, enum rtx_ *** 18412,18430 **** rtx op_true, rtx op_false) { enum machine_mode mode = GET_MODE (dest); rtx x; ! cmp_op0 = force_reg (mode, cmp_op0); ! if (!nonimmediate_operand (cmp_op1, mode)) ! cmp_op1 = force_reg (mode, cmp_op1); if (optimize || reg_overlap_mentioned_p (dest, op_true) || reg_overlap_mentioned_p (dest, op_false)) dest = gen_reg_rtx (mode); ! x = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); ! emit_insn (gen_rtx_SET (VOIDmode, dest, x)); return dest; } --- 18412,18437 ---- rtx op_true, rtx op_false) { enum machine_mode mode = GET_MODE (dest); + enum machine_mode cmp_mode = GET_MODE (cmp_op0); rtx x; ! cmp_op0 = force_reg (cmp_mode, cmp_op0); ! if (!nonimmediate_operand (cmp_op1, cmp_mode)) ! cmp_op1 = force_reg (cmp_mode, cmp_op1); if (optimize || reg_overlap_mentioned_p (dest, op_true) || reg_overlap_mentioned_p (dest, op_false)) dest = gen_reg_rtx (mode); ! x = gen_rtx_fmt_ee (code, cmp_mode, cmp_op0, cmp_op1); ! if (cmp_mode != mode) ! { ! x = force_reg (cmp_mode, x); ! convert_move (dest, x, false); ! } ! else ! emit_insn (gen_rtx_SET (VOIDmode, dest, x)); return dest; } Index: trunk/gcc/tree-vect-stmts.c =================================================================== *** trunk.orig/gcc/tree-vect-stmts.c 2011-08-29 16:57:29.000000000 +0200 --- trunk/gcc/tree-vect-stmts.c 2011-08-29 16:57:41.000000000 +0200 *************** vectorizable_load (gimple stmt, gimple_s *** 4680,4694 **** LOOP - the loop that is being vectorized. COND - Condition that is checked for simple use. Returns whether a COND can be vectorized. Checks whether condition operands are supportable using vec_is_simple_use. */ static bool ! vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo) { tree lhs, rhs; tree def; enum vect_def_type dt; if (!COMPARISON_CLASS_P (cond)) return false; --- 4680,4698 ---- LOOP - the loop that is being vectorized. COND - Condition that is checked for simple use. + Output: + *COMP_VECTYPE - the vector type for the comparison. + Returns whether a COND can be vectorized. Checks whether condition operands are supportable using vec_is_simple_use. */ static bool ! vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo, tree *comp_vectype) { tree lhs, rhs; tree def; enum vect_def_type dt; + tree vectype1 = NULL_TREE, vectype2 = NULL_TREE; if (!COMPARISON_CLASS_P (cond)) return false; *************** vect_is_simple_cond (tree cond, loop_vec *** 4699,4706 **** if (TREE_CODE (lhs) == SSA_NAME) { gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs); ! if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def, ! &dt)) return false; } else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST --- 4703,4710 ---- if (TREE_CODE (lhs) == SSA_NAME) { gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs); ! if (!vect_is_simple_use_1 (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def, ! &dt, &vectype1)) return false; } else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST *************** vect_is_simple_cond (tree cond, loop_vec *** 4710,4723 **** if (TREE_CODE (rhs) == SSA_NAME) { gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs); ! if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def, ! &dt)) return false; } else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST && TREE_CODE (rhs) != FIXED_CST) return false; return true; } --- 4714,4728 ---- if (TREE_CODE (rhs) == SSA_NAME) { gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs); ! if (!vect_is_simple_use_1 (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def, ! &dt, &vectype2)) return false; } else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST && TREE_CODE (rhs) != FIXED_CST) return false; + *comp_vectype = vectype1 ? vectype1 : vectype2; return true; } *************** vectorizable_condition (gimple stmt, gim *** 4744,4749 **** --- 4749,4755 ---- tree cond_expr, then_clause, else_clause; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); tree vectype = STMT_VINFO_VECTYPE (stmt_info); + tree comp_vectype; tree vec_cond_lhs = NULL_TREE, vec_cond_rhs = NULL_TREE; tree vec_then_clause = NULL_TREE, vec_else_clause = NULL_TREE; tree vec_compare, vec_cond_expr; *************** vectorizable_condition (gimple stmt, gim *** 4799,4811 **** then_clause = TREE_OPERAND (op, 1); else_clause = TREE_OPERAND (op, 2); ! if (!vect_is_simple_cond (cond_expr, loop_vinfo)) ! return false; ! ! /* We do not handle two different vector types for the condition ! and the values. */ ! if (!types_compatible_p (TREE_TYPE (TREE_OPERAND (cond_expr, 0)), ! TREE_TYPE (vectype))) return false; if (TREE_CODE (then_clause) == SSA_NAME) --- 4805,4812 ---- then_clause = TREE_OPERAND (op, 1); else_clause = TREE_OPERAND (op, 2); ! if (!vect_is_simple_cond (cond_expr, loop_vinfo, &comp_vectype) ! || !comp_vectype) return false; if (TREE_CODE (then_clause) == SSA_NAME) *************** vectorizable_condition (gimple stmt, gim *** 4835,4841 **** if (!vec_stmt) { STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type; ! return expand_vec_cond_expr_p (vectype, vectype); } /* Transform */ --- 4836,4842 ---- if (!vec_stmt) { STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type; ! return expand_vec_cond_expr_p (vectype, comp_vectype); } /* Transform */ Index: trunk/gcc/testsuite/gcc.dg/vect/vect-cond-7.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- trunk/gcc/testsuite/gcc.dg/vect/vect-cond-7.c 2011-08-29 17:04:38.000000000 +0200 *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-require-effective-target vect_condition } */ + + int vis_type[128]; + float vs_data[128]; + void vis_clear_data () + { + int i; + for (i = 0; i < 128; i++) + vs_data[i] = (vis_type[i] == 1); + } + + /* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */ + /* { dg-final { cleanup-tree-dump "vect" } } */