From patchwork Tue Jul 10 08:22:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 170078 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]) by ozlabs.org (Postfix) with SMTP id 834FC2C007E for ; Tue, 10 Jul 2012 18:24:36 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1342513477; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Subject:Date:Message-Id:In-Reply-To:References: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=6RGvOQOGoydQOboKAFdv rXz9dZ8=; b=ChxTA2VSTdjRgn2oIBUN4scGFLwZuS4nkGboDe15UhV+8VhW6Q+U OVca5G51re6HnnOmSiBGk2L1B4ORd9vM+ukwpTqepZYc3wmSKu8O0oT6rKzeBy05 wGfpjyEJaDKIsvvAr4tdYklKJR7MKIwJ3nhPukbgAjVp0rbYW/6Bqjc= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Subject:Date:Message-Id:In-Reply-To:References:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=jssACH82jOWlDqhwNXzT33RZUJdsus1MtU4uLEh3WY+avBS+5Kgx80ZnC+x25y qmMfPOHTEVmsuys2nKvKjg0ofQZCLT9UckoVio1mgD1/AAifouPg/KJk7icAX0p3 mmWUcqjDUl9FZ5exfQYJqGXTfPYs9Xs9Zf5ASKTVrs6+k=; Received: (qmail 31929 invoked by alias); 10 Jul 2012 08:23:30 -0000 Received: (qmail 31832 invoked by uid 22791); 10 Jul 2012 08:23:21 -0000 X-SWARE-Spam-Status: No, hits=-5.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-wg0-f51.google.com (HELO mail-wg0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 10 Jul 2012 08:23:03 +0000 Received: by wgbed3 with SMTP id ed3so254294wgb.8 for ; Tue, 10 Jul 2012 01:23:01 -0700 (PDT) Received: by 10.180.78.197 with SMTP id d5mr36176981wix.7.1341908581852; Tue, 10 Jul 2012 01:23:01 -0700 (PDT) Received: from pebble.cz (vpn-konference.ms.mff.cuni.cz. [195.113.20.101]) by mx.google.com with ESMTPS id ch9sm41442328wib.8.2012.07.10.01.23.00 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 10 Jul 2012 01:23:01 -0700 (PDT) From: Richard Henderson To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/7] Add VEC_WIDEN_MULT_EVEN/ODD_EXPR Date: Tue, 10 Jul 2012 10:22:45 +0200 Message-Id: <1341908571-30346-2-git-send-email-rth@redhat.com> In-Reply-To: <1341908571-30346-1-git-send-email-rth@redhat.com> References: <1341908571-30346-1-git-send-email-rth@redhat.com> X-IsSubscribed: yes 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 * tree.def (VEC_WIDEN_MULT_EVEN_EXPR, VEC_WIDEN_MULT_ODD_EXPR): New. * cfgexpand.c (expand_debug_expr): Handle them. * expr.c (expand_expr_real_2): Likewise. * fold-const.c (fold_binary_loc): Likewise. * gimple-pretty-print.c (dump_binary_rhs): Likewise. * optabs.c (optab_for_tree_code): Likewise. * tree-cfg.c (verify_gimple_assign_binary): Likewise. * tree-inline.c (estimate_operator_cost): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * tree.c (commutative_tree_code): Likewise. * tree-vect-generic.c (expand_vector_operations_1): Likewise. Handle type change before looking up optab. * optabs.h (OTI_vec_widen_umult_even, OTI_vec_widen_umult_odd): New. (OTI_vec_widen_smult_even, OTI_vec_widen_smult_odd): New. (vec_widen_umult_even_optab, vec_widen_umult_odd_optab): New. (vec_widen_smult_even_optab, vec_widen_smult_odd_optab): New. * genopinit.c (optabs): Initialize them. * doc/md.texi: Document them. --- gcc/ChangeLog | 21 +++++++++++++++++++++ gcc/cfgexpand.c | 4 +++- gcc/doc/md.texi | 12 +++++++++--- gcc/expr.c | 28 +++++++--------------------- gcc/fold-const.c | 36 ++++++++++++++++++++++++------------ gcc/genopinit.c | 4 ++++ gcc/gimple-pretty-print.c | 2 ++ gcc/optabs.c | 8 ++++++++ gcc/optabs.h | 12 ++++++++++-- gcc/tree-cfg.c | 2 ++ gcc/tree-inline.c | 2 ++ gcc/tree-pretty-print.c | 32 +++++++++----------------------- gcc/tree-vect-generic.c | 32 +++++++++++++++++--------------- gcc/tree.c | 2 ++ gcc/tree.def | 4 ++++ 15 files changed, 124 insertions(+), 77 deletions(-) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index ad2f667..c8d09c7 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1,5 +1,5 @@ /* A pass for lowering trees to RTL. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -3410,6 +3410,8 @@ expand_debug_expr (tree exp) case VEC_UNPACK_LO_EXPR: case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: case VEC_WIDEN_LSHIFT_HI_EXPR: case VEC_WIDEN_LSHIFT_LO_EXPR: case VEC_PERM_EXPR: diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index c71c59c..99f6528 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4561,15 +4561,21 @@ floating point conversion and place the resulting N/2 values of size 2*S in the output vector (operand 0). @cindex @code{vec_widen_umult_hi_@var{m}} instruction pattern -@cindex @code{vec_widen_umult_lo__@var{m}} instruction pattern +@cindex @code{vec_widen_umult_lo_@var{m}} instruction pattern @cindex @code{vec_widen_smult_hi_@var{m}} instruction pattern @cindex @code{vec_widen_smult_lo_@var{m}} instruction pattern +@cindex @code{vec_widen_umult_even_@var{m}} instruction pattern +@cindex @code{vec_widen_umult_odd_@var{m}} instruction pattern +@cindex @code{vec_widen_smult_even_@var{m}} instruction pattern +@cindex @code{vec_widen_smult_odd_@var{m}} instruction pattern @item @samp{vec_widen_umult_hi_@var{m}}, @samp{vec_widen_umult_lo_@var{m}} @itemx @samp{vec_widen_smult_hi_@var{m}}, @samp{vec_widen_smult_lo_@var{m}} +@itemx @samp{vec_widen_umult_even_@var{m}}, @samp{vec_widen_umult_odd_@var{m}} +@itemx @samp{vec_widen_smult_even_@var{m}}, @samp{vec_widen_smult_odd_@var{m}} Signed/Unsigned widening multiplication. The two inputs (operands 1 and 2) are vectors with N signed/unsigned elements of size S@. Multiply the high/low -elements of the two vectors, and put the N/2 products of size 2*S in the -output vector (operand 0). +or even/odd elements of the two vectors, and put the N/2 products of size 2*S +in the output vector (operand 0). @cindex @code{vec_widen_ushiftl_hi_@var{m}} instruction pattern @cindex @code{vec_widen_ushiftl_lo_@var{m}} instruction pattern diff --git a/gcc/expr.c b/gcc/expr.c index 1279186..c56b0e5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8917,29 +8917,15 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: - { - tree oprnd0 = treeop0; - tree oprnd1 = treeop1; - - expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); - target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX, - target, unsignedp); - gcc_assert (target); - return target; - } - + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: case VEC_WIDEN_LSHIFT_HI_EXPR: case VEC_WIDEN_LSHIFT_LO_EXPR: - { - tree oprnd0 = treeop0; - tree oprnd1 = treeop1; - - expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); - target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX, - target, unsignedp); - gcc_assert (target); - return target; - } + expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); + target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX, + target, unsignedp); + gcc_assert (target); + return target; case VEC_PACK_TRUNC_EXPR: case VEC_PACK_SAT_EXPR: diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 702f4e0..a491499 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -13657,8 +13657,11 @@ fold_binary_loc (location_t loc, case VEC_WIDEN_MULT_LO_EXPR: case VEC_WIDEN_MULT_HI_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: { - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; + unsigned int nelts = TYPE_VECTOR_SUBPARTS (type); + unsigned int out, ofs, scale; tree *elts; gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2 @@ -13671,19 +13674,28 @@ fold_binary_loc (location_t loc, || !vec_cst_ctor_to_array (arg1, elts + nelts * 2)) return NULL_TREE; - if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_WIDEN_MULT_LO_EXPR)) - elts += nelts; - - for (i = 0; i < nelts; i++) + if (code == VEC_WIDEN_MULT_LO_EXPR) + scale = 0, ofs = BYTES_BIG_ENDIAN ? nelts : 0; + else if (code == VEC_WIDEN_MULT_HI_EXPR) + scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : nelts; + else if (code == VEC_WIDEN_MULT_EVEN_EXPR) + scale = 1, ofs = 0; + else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */ + scale = 1, ofs = 1; + + for (out = 0; out < nelts; out++) { - elts[i] = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[i]); - elts[i + nelts * 2] - = fold_convert_const (NOP_EXPR, TREE_TYPE (type), - elts[i + nelts * 2]); - if (elts[i] == NULL_TREE || elts[i + nelts * 2] == NULL_TREE) + unsigned int in1 = (out << scale) + ofs; + unsigned int in2 = in1 + nelts * 2; + tree t1, t2; + + t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]); + t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in2]); + + if (t1 == NULL_TREE || t2 == NULL_TREE) return NULL_TREE; - elts[i] = const_binop (MULT_EXPR, elts[i], elts[i + nelts * 2]); - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) + elts[out] = const_binop (MULT_EXPR, t1, t2); + if (elts[out] == NULL_TREE || !CONSTANT_CLASS_P (elts[out])) return NULL_TREE; } diff --git a/gcc/genopinit.c b/gcc/genopinit.c index baccd45..2d6757e 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -289,6 +289,10 @@ static const char * const optabs[] = "set_optab_handler (vec_widen_umult_lo_optab, $A, CODE_FOR_$(vec_widen_umult_lo_$a$))", "set_optab_handler (vec_widen_smult_hi_optab, $A, CODE_FOR_$(vec_widen_smult_hi_$a$))", "set_optab_handler (vec_widen_smult_lo_optab, $A, CODE_FOR_$(vec_widen_smult_lo_$a$))", + "set_optab_handler (vec_widen_umult_even_optab, $A, CODE_FOR_$(vec_widen_umult_even_$a$))", + "set_optab_handler (vec_widen_umult_odd_optab, $A, CODE_FOR_$(vec_widen_umult_odd_$a$))", + "set_optab_handler (vec_widen_smult_even_optab, $A, CODE_FOR_$(vec_widen_smult_even_$a$))", + "set_optab_handler (vec_widen_smult_odd_optab, $A, CODE_FOR_$(vec_widen_smult_odd_$a$))", "set_optab_handler (vec_widen_ushiftl_hi_optab, $A, CODE_FOR_$(vec_widen_ushiftl_hi_$a$))", "set_optab_handler (vec_widen_ushiftl_lo_optab, $A, CODE_FOR_$(vec_widen_ushiftl_lo_$a$))", "set_optab_handler (vec_widen_sshiftl_hi_optab, $A, CODE_FOR_$(vec_widen_sshiftl_hi_$a$))", diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index a80ae90..648597a 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -342,6 +342,8 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags) case MAX_EXPR: case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: case VEC_PACK_TRUNC_EXPR: case VEC_PACK_SAT_EXPR: case VEC_PACK_FIX_TRUNC_EXPR: diff --git a/gcc/optabs.c b/gcc/optabs.c index 3094476..fbea879 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -483,6 +483,14 @@ optab_for_tree_code (enum tree_code code, const_tree type, return TYPE_UNSIGNED (type) ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab; + case VEC_WIDEN_MULT_EVEN_EXPR: + return TYPE_UNSIGNED (type) ? + vec_widen_umult_even_optab : vec_widen_smult_even_optab; + + case VEC_WIDEN_MULT_ODD_EXPR: + return TYPE_UNSIGNED (type) ? + vec_widen_umult_odd_optab : vec_widen_smult_odd_optab; + case VEC_WIDEN_LSHIFT_HI_EXPR: return TYPE_UNSIGNED (type) ? vec_widen_ushiftl_hi_optab : vec_widen_sshiftl_hi_optab; diff --git a/gcc/optabs.h b/gcc/optabs.h index d87aff8..37a6bfd 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -340,12 +340,16 @@ enum optab_index OTI_vec_shr, /* Extract specified elements from vectors, for vector load. */ OTI_vec_realign_load, - /* Widening multiplication. - The high/low part of the resulting vector of products is returned. */ + /* Widening multiplication. The high/low/even/odd part of the + resulting vector of products is returned. */ OTI_vec_widen_umult_hi, OTI_vec_widen_umult_lo, OTI_vec_widen_smult_hi, OTI_vec_widen_smult_lo, + OTI_vec_widen_umult_even, + OTI_vec_widen_umult_odd, + OTI_vec_widen_smult_even, + OTI_vec_widen_smult_odd, /* Widening shift left. The high/low part of the resulting vector is returned. */ OTI_vec_widen_ushiftl_hi, @@ -565,6 +569,10 @@ enum optab_index #define vec_widen_umult_lo_optab (&optab_table[OTI_vec_widen_umult_lo]) #define vec_widen_smult_hi_optab (&optab_table[OTI_vec_widen_smult_hi]) #define vec_widen_smult_lo_optab (&optab_table[OTI_vec_widen_smult_lo]) +#define vec_widen_umult_even_optab (&optab_table[OTI_vec_widen_umult_even]) +#define vec_widen_umult_odd_optab (&optab_table[OTI_vec_widen_umult_odd]) +#define vec_widen_smult_even_optab (&optab_table[OTI_vec_widen_smult_even]) +#define vec_widen_smult_odd_optab (&optab_table[OTI_vec_widen_smult_odd]) #define vec_widen_ushiftl_hi_optab (&optab_table[OTI_vec_widen_ushiftl_hi]) #define vec_widen_ushiftl_lo_optab (&optab_table[OTI_vec_widen_ushiftl_lo]) #define vec_widen_sshiftl_hi_optab (&optab_table[OTI_vec_widen_sshiftl_hi]) diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index e03313e..d8a396f 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3724,6 +3724,8 @@ do_pointer_plus_expr_check: case WIDEN_SUM_EXPR: case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: case VEC_PACK_TRUNC_EXPR: case VEC_PACK_SAT_EXPR: case VEC_PACK_FIX_TRUNC_EXPR: diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 7d444e1..f576ee5 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3456,6 +3456,8 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights, case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: case VEC_UNPACK_HI_EXPR: case VEC_UNPACK_LO_EXPR: case VEC_UNPACK_FLOAT_HI_EXPR: diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index f418d39..cdf3f28 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -602,6 +602,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, tree op0, op1; const char *str; bool is_expr; + enum tree_code code; if (node == NULL_TREE) return spc; @@ -614,7 +615,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node)) dump_location (buffer, EXPR_LOCATION (node)); - switch (TREE_CODE (node)) + code = TREE_CODE (node); + switch (code) { case ERROR_MARK: pp_string (buffer, "<<< error >>>"); @@ -2336,31 +2338,15 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, break; case VEC_WIDEN_MULT_HI_EXPR: - pp_string (buffer, " VEC_WIDEN_MULT_HI_EXPR < "); - dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); - pp_string (buffer, ", "); - dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); - pp_string (buffer, " > "); - break; - case VEC_WIDEN_MULT_LO_EXPR: - pp_string (buffer, " VEC_WIDEN_MULT_LO_EXPR < "); - dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); - pp_string (buffer, ", "); - dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); - pp_string (buffer, " > "); - break; - + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: case VEC_WIDEN_LSHIFT_HI_EXPR: - pp_string (buffer, " VEC_WIDEN_LSHIFT_HI_EXPR < "); - dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); - pp_string (buffer, ", "); - dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); - pp_string (buffer, " > "); - break; - case VEC_WIDEN_LSHIFT_LO_EXPR: - pp_string (buffer, " VEC_WIDEN_LSHIFT_HI_EXPR < "); + pp_character (buffer, ' '); + for (str = tree_code_name [code]; *str; str++) + pp_character (buffer, TOUPPER (*str)); + pp_string (buffer, " < "); dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); pp_string (buffer, ", "); dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 8d05101..e37c631 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -1361,6 +1361,23 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi) || code == VEC_UNPACK_FLOAT_LO_EXPR) type = TREE_TYPE (rhs1); + /* For widening/narrowing vector operations, the relevant type is of the + arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is + calculated in the same way above. */ + if (code == WIDEN_SUM_EXPR + || code == VEC_WIDEN_MULT_HI_EXPR + || code == VEC_WIDEN_MULT_LO_EXPR + || code == VEC_WIDEN_MULT_EVEN_EXPR + || code == VEC_WIDEN_MULT_ODD_EXPR + || code == VEC_UNPACK_HI_EXPR + || code == VEC_UNPACK_LO_EXPR + || code == VEC_PACK_TRUNC_EXPR + || code == VEC_PACK_SAT_EXPR + || code == VEC_PACK_FIX_TRUNC_EXPR + || code == VEC_WIDEN_LSHIFT_HI_EXPR + || code == VEC_WIDEN_LSHIFT_LO_EXPR) + type = TREE_TYPE (rhs1); + /* Choose between vector shift/rotate by vector and vector shift/rotate by scalar */ if (code == LSHIFT_EXPR @@ -1409,21 +1426,6 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi) else op = optab_for_tree_code (code, type, optab_default); - /* For widening/narrowing vector operations, the relevant type is of the - arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is - calculated in the same way above. */ - if (code == WIDEN_SUM_EXPR - || code == VEC_WIDEN_MULT_HI_EXPR - || code == VEC_WIDEN_MULT_LO_EXPR - || code == VEC_UNPACK_HI_EXPR - || code == VEC_UNPACK_LO_EXPR - || code == VEC_PACK_TRUNC_EXPR - || code == VEC_PACK_SAT_EXPR - || code == VEC_PACK_FIX_TRUNC_EXPR - || code == VEC_WIDEN_LSHIFT_HI_EXPR - || code == VEC_WIDEN_LSHIFT_LO_EXPR) - type = TREE_TYPE (rhs1); - /* Optabs will try converting a negation into a subtraction, so look for it as well. TODO: negation of floating-point vectors might be turned into an exclusive OR toggling the sign bit. */ diff --git a/gcc/tree.c b/gcc/tree.c index f92f070..d10b9ab 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6927,6 +6927,8 @@ commutative_tree_code (enum tree_code code) case WIDEN_MULT_EXPR: case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: + case VEC_WIDEN_MULT_EVEN_EXPR: + case VEC_WIDEN_MULT_ODD_EXPR: return true; default: diff --git a/gcc/tree.def b/gcc/tree.def index b0d4aea..70188ff 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1171,6 +1171,10 @@ DEFTREECODE (VEC_RSHIFT_EXPR, "vec_rshift_expr", tcc_binary, 2) DEFTREECODE (VEC_WIDEN_MULT_HI_EXPR, "widen_mult_hi_expr", tcc_binary, 2) DEFTREECODE (VEC_WIDEN_MULT_LO_EXPR, "widen_mult_lo_expr", tcc_binary, 2) +/* Similarly, but return the even or odd N/2 products. */ +DEFTREECODE (VEC_WIDEN_MULT_EVEN_EXPR, "widen_mult_even_expr", tcc_binary, 2) +DEFTREECODE (VEC_WIDEN_MULT_ODD_EXPR, "widen_mult_odd_expr", tcc_binary, 2) + /* Unpack (extract and promote/widen) the high/low elements of the input vector into the output vector. The input vector has twice as many elements as the output vector, that are half the size of the elements