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<mode>/vcond<mode><mode>/.  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  <rguent...@suse.de>

        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" } } */

Reply via email to