aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2012-07-10 01:23:39 -0700
committerRichard Henderson <rth@gcc.gnu.org>2012-07-10 01:23:39 -0700
commit3f30a9a6aabcc7408bec1e42736889e3edd9f289 (patch)
tree3004b5ca9b3236230ebbc1657f1529e32ff03d51
parente53a3e778e70af499292522144fb8d4bea5279cb (diff)
downloadgcc-3f30a9a6aabcc7408bec1e42736889e3edd9f289.zip
gcc-3f30a9a6aabcc7408bec1e42736889e3edd9f289.tar.gz
gcc-3f30a9a6aabcc7408bec1e42736889e3edd9f289.tar.bz2
Add VEC_WIDEN_MULT_EVEN/ODD_EXPR
* 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. From-SVN: r189403
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/cfgexpand.c4
-rw-r--r--gcc/doc/md.texi12
-rw-r--r--gcc/expr.c28
-rw-r--r--gcc/fold-const.c36
-rw-r--r--gcc/genopinit.c4
-rw-r--r--gcc/gimple-pretty-print.c2
-rw-r--r--gcc/optabs.c8
-rw-r--r--gcc/optabs.h12
-rw-r--r--gcc/tree-cfg.c2
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/tree-pretty-print.c32
-rw-r--r--gcc/tree-vect-generic.c32
-rw-r--r--gcc/tree.c2
-rw-r--r--gcc/tree.def4
15 files changed, 124 insertions, 77 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 533e844..a65b78e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2012-07-10 Richard Henderson <rth@redhat.com>
+
+ * 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.
+
2012-07-10 Dehao Chen <dehao@google.com>
* tree.h (phi_arg_d): New field.
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