[PATCH] Move VEC_PERM_EXPR folding to match.pd
Richard Biener
rguenther@suse.de
Mon May 20 08:52:00 GMT 2019
On Fri, 17 May 2019, Richard Biener wrote:
>
> This moves things from fold-const.c to match.pd.
So there's an issue that was appearantly side-stepped in the GENERIC
folding by not re-folding the result.
/* Generate a canonical form of the selector. */
if (sel.encoding () != builder)
"spuriously" returns true for some cases where we end up with
the same tree representation of the selector (I see
m_npatterns == 4 vs. 1 and m_nelts_per_pattern 1 vs. 3).
So I either have to double-check whether the re-created
op2 is really different from the original one or remove
those "premature" checks from vector_builder::operator==
where we then no longer can compare encoded elts...
Testing the variant with changed = operand_equal_p (...).
Richard.
> Bootstrap / regtest running on x86_64-unknown-linux-gnu.
>
> Richard.
>
> 2019-05-17 Richard Biener <rguenther@suse.de>
>
> * gimple-match-head.c: Include vec-perm-indices.h.
> * generic-match-head.c: Likewise.
> * fold-const.h (fold_vec_perm): Declare when vec-perm-indices.h
> is included.
> * fold-const.c (fold_vec_perm): Export.
> (fold_ternary_loc): Move non-constant folding of VEC_PERM_EXPR...
> (match.pd): ...here.
>
> Index: gcc/gimple-match-head.c
> ===================================================================
> --- gcc/gimple-match-head.c (revision 271320)
> +++ gcc/gimple-match-head.c (working copy)
> @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.
> #include "gimple.h"
> #include "ssa.h"
> #include "cgraph.h"
> +#include "vec-perm-indices.h"
> #include "fold-const.h"
> #include "fold-const-call.h"
> #include "stor-layout.h"
> Index: gcc/generic-match-head.c
> ===================================================================
> --- gcc/generic-match-head.c (revision 271320)
> +++ gcc/generic-match-head.c (working copy)
> @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.
> #include "gimple.h"
> #include "ssa.h"
> #include "cgraph.h"
> +#include "vec-perm-indices.h"
> #include "fold-const.h"
> #include "stor-layout.h"
> #include "tree-dfa.h"
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c (revision 271320)
> +++ gcc/fold-const.c (working copy)
> @@ -9015,7 +9015,7 @@ vec_cst_ctor_to_array (tree arg, unsigne
> selector. Return the folded VECTOR_CST or CONSTRUCTOR if successful,
> NULL_TREE otherwise. */
>
> -static tree
> +tree
> fold_vec_perm (tree type, tree arg0, tree arg1, const vec_perm_indices &sel)
> {
> unsigned int i;
> @@ -11763,7 +11763,10 @@ fold_ternary_loc (location_t loc, enum t
> return NULL_TREE;
>
> case VEC_PERM_EXPR:
> - if (TREE_CODE (arg2) == VECTOR_CST)
> + /* Perform constant folding of BIT_INSERT_EXPR. */
> + if (TREE_CODE (arg2) == VECTOR_CST
> + && TREE_CODE (op0) == VECTOR_CST
> + && TREE_CODE (op1) == VECTOR_CST)
> {
> /* Build a vector of integers from the tree mask. */
> vec_perm_builder builder;
> @@ -11774,61 +11777,7 @@ fold_ternary_loc (location_t loc, enum t
> poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
> bool single_arg = (op0 == op1);
> vec_perm_indices sel (builder, single_arg ? 1 : 2, nelts);
> -
> - /* Check for cases that fold to OP0 or OP1 in their original
> - element order. */
> - if (sel.series_p (0, 1, 0, 1))
> - return op0;
> - if (sel.series_p (0, 1, nelts, 1))
> - return op1;
> -
> - if (!single_arg)
> - {
> - if (sel.all_from_input_p (0))
> - op1 = op0;
> - else if (sel.all_from_input_p (1))
> - {
> - op0 = op1;
> - sel.rotate_inputs (1);
> - }
> - }
> -
> - if ((TREE_CODE (op0) == VECTOR_CST
> - || TREE_CODE (op0) == CONSTRUCTOR)
> - && (TREE_CODE (op1) == VECTOR_CST
> - || TREE_CODE (op1) == CONSTRUCTOR))
> - {
> - tree t = fold_vec_perm (type, op0, op1, sel);
> - if (t != NULL_TREE)
> - return t;
> - }
> -
> - bool changed = (op0 == op1 && !single_arg);
> -
> - /* Generate a canonical form of the selector. */
> - if (arg2 == op2 && sel.encoding () != builder)
> - {
> - /* Some targets are deficient and fail to expand a single
> - argument permutation while still allowing an equivalent
> - 2-argument version. */
> - if (sel.ninputs () == 2
> - || can_vec_perm_const_p (TYPE_MODE (type), sel, false))
> - op2 = vec_perm_indices_to_tree (TREE_TYPE (arg2), sel);
> - else
> - {
> - vec_perm_indices sel2 (builder, 2, nelts);
> - if (can_vec_perm_const_p (TYPE_MODE (type), sel2, false))
> - op2 = vec_perm_indices_to_tree (TREE_TYPE (arg2), sel2);
> - else
> - /* Not directly supported with either encoding,
> - so use the preferred form. */
> - op2 = vec_perm_indices_to_tree (TREE_TYPE (arg2), sel);
> - }
> - changed = true;
> - }
> -
> - if (changed)
> - return build3_loc (loc, VEC_PERM_EXPR, type, op0, op1, op2);
> + return fold_vec_perm (type, op0, op1, sel);
> }
> return NULL_TREE;
>
> Index: gcc/fold-const.h
> ===================================================================
> --- gcc/fold-const.h (revision 271320)
> +++ gcc/fold-const.h (working copy)
> @@ -100,6 +100,9 @@ extern tree fold_bit_and_mask (tree, tre
> tree, enum tree_code, tree, tree,
> tree, enum tree_code, tree, tree, tree *);
> extern tree fold_read_from_constant_string (tree);
> +#if GCC_VEC_PERN_INDICES_H
> +extern tree fold_vec_perm (tree, tree, tree, const vec_perm_indices &);
> +#endif
> extern bool wide_int_binop (wide_int &res, enum tree_code,
> const wide_int &arg1, const wide_int &arg2,
> signop, wi::overflow_type *);
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd (revision 271320)
> +++ gcc/match.pd (working copy)
> @@ -5374,3 +5374,83 @@ (define_operator_list COND_TERNARY
> (bit_and:elt_type
> (BIT_FIELD_REF:elt_type @0 { size; } { pos; })
> { elt; })))))))
> +
> +(simplify
> + (vec_perm @0 @1 VECTOR_CST@2)
> + (with
> + {
> + tree op0 = @0, op1 = @1, op2 = @2;
> +
> + /* Build a vector of integers from the tree mask. */
> + vec_perm_builder builder;
> + if (!tree_to_vec_perm_builder (&builder, op2))
> + return NULL_TREE;
> +
> + /* Create a vec_perm_indices for the integer vector. */
> + poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
> + bool single_arg = (op0 == op1);
> + vec_perm_indices sel (builder, single_arg ? 1 : 2, nelts);
> + }
> + (if (sel.series_p (0, 1, 0, 1))
> + { op0; }
> + (if (sel.series_p (0, 1, nelts, 1))
> + { op1; }
> + (with
> + {
> + if (!single_arg)
> + {
> + if (sel.all_from_input_p (0))
> + op1 = op0;
> + else if (sel.all_from_input_p (1))
> + {
> + op0 = op1;
> + sel.rotate_inputs (1);
> + }
> + }
> + gassign *def;
> + tree cop0 = op0, cop1 = op1;
> + if (TREE_CODE (op0) == SSA_NAME
> + && (def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0)))
> + && gimple_assign_rhs_code (def) == CONSTRUCTOR)
> + cop0 = gimple_assign_rhs1 (def);
> + if (TREE_CODE (op1) == SSA_NAME
> + && (def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op1)))
> + && gimple_assign_rhs_code (def) == CONSTRUCTOR)
> + cop1 = gimple_assign_rhs1 (def);
> +
> + tree t;
> + }
> + (if ((TREE_CODE (cop0) == VECTOR_CST
> + || TREE_CODE (cop0) == CONSTRUCTOR)
> + && (TREE_CODE (cop1) == VECTOR_CST
> + || TREE_CODE (cop1) == CONSTRUCTOR)
> + && (t = fold_vec_perm (type, cop0, cop1, sel)))
> + { t; }
> + (with
> + {
> + bool changed = (op0 == op1 && !single_arg);
> +
> + /* Generate a canonical form of the selector. */
> + if (sel.encoding () != builder)
> + {
> + /* Some targets are deficient and fail to expand a single
> + argument permutation while still allowing an equivalent
> + 2-argument version. */
> + if (sel.ninputs () == 2
> + || can_vec_perm_const_p (TYPE_MODE (type), sel, false))
> + op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel);
> + else
> + {
> + vec_perm_indices sel2 (builder, 2, nelts);
> + if (can_vec_perm_const_p (TYPE_MODE (type), sel2, false))
> + op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2);
> + else
> + /* Not directly supported with either encoding,
> + so use the preferred form. */
> + op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel);
> + }
> + changed = true;
> + }
> + }
> + (if (changed)
> + (vec_perm { op0; } { op1; } { op2; })))))))))
>
--
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)
More information about the Gcc-patches
mailing list