On Fri, Oct 12, 2012 at 4:07 PM, Marc Glisse <[email protected]> wrote:
> On Sat, 29 Sep 2012, Marc Glisse wrote:
>
>> 1) it handles constant folding of vector comparisons,
>>
>> 2) it fixes another place where vectors are not expected
>
>
> Here is a new version of this patch.
>
> In a first try, I got bitten by the operator priorities in "a && b?c:d",
> which g++ doesn't warn about.
>
>
> 2012-10-12 Marc Glisse <[email protected]>
>
> gcc/
> * tree-ssa-forwprop.c (forward_propagate_into_cond): Handle vectors.
>
> * fold-const.c (fold_relational_const): Handle VECTOR_CST.
>
> gcc/testsuite/
> * gcc.dg/tree-ssa/foldconst-6.c: New testcase.
>
> --
> Marc Glisse
>
> Index: gcc/tree-ssa-forwprop.c
> ===================================================================
> --- gcc/tree-ssa-forwprop.c (revision 192400)
> +++ gcc/tree-ssa-forwprop.c (working copy)
> @@ -570,40 +570,43 @@ forward_propagate_into_cond (gimple_stmt
> code = gimple_assign_rhs_code (def_stmt);
> if (TREE_CODE_CLASS (code) == tcc_comparison)
> tmp = fold_build2_loc (gimple_location (def_stmt),
> code,
> TREE_TYPE (cond),
> gimple_assign_rhs1 (def_stmt),
> gimple_assign_rhs2 (def_stmt));
> else if ((code == BIT_NOT_EXPR
> && TYPE_PRECISION (TREE_TYPE (cond)) == 1)
> || (code == BIT_XOR_EXPR
> - && integer_onep (gimple_assign_rhs2 (def_stmt))))
> + && ((gimple_assign_rhs_code (stmt) == VEC_COND_EXPR)
> + ? integer_all_onesp (gimple_assign_rhs2 (def_stmt))
> + : integer_onep (gimple_assign_rhs2 (def_stmt)))))
I don't think that we can do anything for vectors here. The non-vector
path assumes that the type is a boolean type (thus two-valued), but
for vectors we can have arbitrary integer value input. Thus, as we
defined true to -1 and false to 0 we cannot, unless relaxing what
VEC_COND_EXRP treats as true or false, optimize any of ~ or ^ -1
away.
Which means I'd prefer if you simply condition the existing ~ and ^
handling on COND_EXPR.
> {
> tmp = gimple_assign_rhs1 (def_stmt);
> swap = true;
> }
> }
>
> if (tmp
> && is_gimple_condexpr (tmp))
> {
> if (dump_file && tmp)
> {
> fprintf (dump_file, " Replaced '");
> print_generic_expr (dump_file, cond, 0);
> fprintf (dump_file, "' with '");
> print_generic_expr (dump_file, tmp, 0);
> fprintf (dump_file, "'\n");
> }
>
> - if (integer_onep (tmp))
> + if ((gimple_assign_rhs_code (stmt) == VEC_COND_EXPR)
> + ? integer_all_onesp (tmp) : integer_onep (tmp))
and cache gimple_assign_rhs_code as a 'code' variable at the beginning
of the function.
> gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs2 (stmt));
> else if (integer_zerop (tmp))
> gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
> else
> {
> gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
> if (swap)
> {
> tree t = gimple_assign_rhs2 (stmt);
> gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt));
> Index: gcc/testsuite/gcc.dg/tree-ssa/foldconst-6.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/foldconst-6.c (revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/foldconst-6.c (revision 0)
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-ccp1" } */
> +
> +typedef long vec __attribute__ ((vector_size (2 * sizeof(long))));
> +
> +vec f ()
> +{
> + vec a = { -2, 666 };
> + vec b = { 3, 2 };
> + return a < b;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "666" "ccp1"} } */
> +/* { dg-final { cleanup-tree-dump "ccp1" } } */
>
> Property changes on: gcc/testsuite/gcc.dg/tree-ssa/foldconst-6.c
> ___________________________________________________________________
> Added: svn:keywords
> + Author Date Id Revision URL
> Added: svn:eol-style
> + native
>
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c (revision 192400)
> +++ gcc/fold-const.c (working copy)
> @@ -16121,20 +16121,44 @@ fold_relational_const (enum tree_code co
> TREE_IMAGPART (op0),
> TREE_IMAGPART (op1));
> if (code == EQ_EXPR)
> return fold_build2 (TRUTH_ANDIF_EXPR, type, rcond, icond);
> else if (code == NE_EXPR)
> return fold_build2 (TRUTH_ORIF_EXPR, type, rcond, icond);
> else
> return NULL_TREE;
> }
>
> + if (TREE_CODE (op0) == VECTOR_CST && TREE_CODE (op1) == VECTOR_CST)
> + {
> + int count = VECTOR_CST_NELTS (op0);
> + tree *elts = XALLOCAVEC (tree, count);
> + gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
A better check would be that VECTOR_CST_NELTS of type is the same
as that of op0.
Ok with these changes.
Thanks,
Richard.
> +
> + for (int i = 0; i < count; i++)
> + {
> + tree elem_type = TREE_TYPE (type);
> + tree elem0 = VECTOR_CST_ELT (op0, i);
> + tree elem1 = VECTOR_CST_ELT (op1, i);
> +
> + tree tem = fold_relational_const (code, elem_type,
> + elem0, elem1);
> +
> + if (tem == NULL_TREE)
> + return NULL_TREE;
> +
> + elts[i] = build_int_cst (elem_type, integer_zerop (tem) ? 0 : -1);
> + }
> +
> + return build_vector (type, elts);
> + }
> +
> /* From here on we only handle LT, LE, GT, GE, EQ and NE.
>
> To compute GT, swap the arguments and do LT.
> To compute GE, do LT and invert the result.
> To compute LE, swap the arguments, do LT and invert the result.
> To compute NE, do EQ and invert the result.
>
> Therefore, the code below must handle only EQ and LT. */
>
> if (code == LE_EXPR || code == GT_EXPR)
>