Patchwork Lower unsupported VEC_COND_EXPR

login
register
mail settings
Submitter Marc Glisse
Date Nov. 1, 2012, 3:44 p.m.
Message ID <alpine.DEB.2.02.1211011613150.9577@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/196258/
State New
Headers show

Comments

Marc Glisse - Nov. 1, 2012, 3:44 p.m.
Hello,

this patch adds support for VEC_COND_EXPR to tree-vect-generic.c. It 
doesn't try to use vectors of smaller size and jumps straight to 
elementwise operations, so there is margin for improvements, but it seemed 
better to have something asap that at least compiles.

For the testsuite: the restrictions in vector19.C were useless, they dated 
from a version that didn't test for errors. The new testcase is for my 
previous patch, but needed this one.


I noticed 2 things while working on this patch:
* there is no dead code elimination after the last forwprop pass
* constant propagation doesn't really work for vectors


bootstrap+testsuite on x86_64-linux, some manual tests with -m32 
-march=i486.

2012-11-01  Marc Glisse  <marc.glisse@inria.fr>

 	PR middle-end/55001

gcc/
 	tree-vect-generic.c (expand_vector_condition): New function.
 	(expand_vector_operations_1): Call it.

testsuite/
 	g++.dg/ext/vector19.C: Remove target restrictions.
 	gcc.dg/fold-compare-7.c: New testcase.
Richard Henderson - Nov. 1, 2012, 11:06 p.m.
On 2012-11-02 02:44, Marc Glisse wrote:
> 2012-11-01  Marc Glisse  <marc.glisse@inria.fr>
> 
>     PR middle-end/55001
> 
> gcc/
>     tree-vect-generic.c (expand_vector_condition): New function.
>     (expand_vector_operations_1): Call it.
> 
> testsuite/
>     g++.dg/ext/vector19.C: Remove target restrictions.
>     gcc.dg/fold-compare-7.c: New testcase.

Ok.


r~

Patch

Index: gcc/testsuite/gcc.dg/fold-compare-7.c

===================================================================
--- gcc/testsuite/gcc.dg/fold-compare-7.c	(revision 0)

+++ gcc/testsuite/gcc.dg/fold-compare-7.c	(revision 0)

@@ -0,0 +1,8 @@ 

+/* { dg-do compile } */

+/* { dg-options "-O2" } */

+

+typedef float vecf __attribute__((vector_size(8*sizeof(float))));

+

+long f(vecf *f1, vecf *f2){

+  return ((*f1 == *f2) < 0)[2];

+}


Property changes on: gcc/testsuite/gcc.dg/fold-compare-7.c
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision URL
Added: svn:eol-style
   + native

Index: gcc/testsuite/g++.dg/ext/vector19.C

===================================================================
--- gcc/testsuite/g++.dg/ext/vector19.C	(revision 193060)

+++ gcc/testsuite/g++.dg/ext/vector19.C	(working copy)

@@ -1,15 +1,12 @@ 

-/* { dg-do compile { target i?86-*-* x86_64-*-* } } */

-/* { dg-options "-std=c++11 -mavx2" } */

-

-// The target restrictions and the -mavx2 flag are meant to disappear

-// once vector lowering is in place.

+/* { dg-do compile } */

+/* { dg-options "-std=c++11" } */

 
 typedef double vec __attribute__((vector_size(2*sizeof(double))));
 typedef signed char vec2 __attribute__((vector_size(16)));
 typedef unsigned char vec2u __attribute__((vector_size(16)));
 
 void f (vec *x, vec *y, vec *z)
 {
   *x = (*y < *z) ? *x : *y;
 }
 
Index: gcc/tree-vect-generic.c

===================================================================
--- gcc/tree-vect-generic.c	(revision 193060)

+++ gcc/tree-vect-generic.c	(working copy)

@@ -861,20 +861,86 @@  expand_vector_divmod (gimple_stmt_iterat

       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
     return NULL_TREE;
   tem = gimplify_build2 (gsi, MULT_EXPR, type, cur_op, op1);
   op = optab_for_tree_code (MINUS_EXPR, type, optab_default);
   if (op == unknown_optab
       || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
     return NULL_TREE;
   return gimplify_build2 (gsi, MINUS_EXPR, type, op0, tem);
 }
 
+/* Expand a vector condition to scalars, by using many conditions

+   on the vector's elements.  */

+static void

+expand_vector_condition (gimple_stmt_iterator *gsi)

+{

+  gimple stmt = gsi_stmt (*gsi);

+  tree type = gimple_expr_type (stmt);

+  tree a = gimple_assign_rhs1 (stmt);

+  tree a1 = a;

+  tree a2;

+  bool a_is_comparison = false;

+  tree b = gimple_assign_rhs2 (stmt);

+  tree c = gimple_assign_rhs3 (stmt);

+  VEC(constructor_elt,gc) *v;

+  tree constr;

+  tree inner_type = TREE_TYPE (type);

+  tree cond_type = TREE_TYPE (TREE_TYPE (a));

+  tree comp_inner_type = cond_type;

+  tree width = TYPE_SIZE (inner_type);

+  tree index = bitsize_int (0);

+  int nunits = TYPE_VECTOR_SUBPARTS (type);

+  int i;

+  location_t loc = gimple_location (gsi_stmt (*gsi));

+

+  if (TREE_CODE (a) != SSA_NAME)

+    {

+      gcc_assert (COMPARISON_CLASS_P (a));

+      a_is_comparison = true;

+      a1 = TREE_OPERAND (a, 0);

+      a2 = TREE_OPERAND (a, 1);

+      comp_inner_type = TREE_TYPE (TREE_TYPE (a1));

+    }

+

+  if (expand_vec_cond_expr_p (type, TREE_TYPE (a1)))

+    return;

+

+  /* TODO: try and find a smaller vector type.  */

+

+  warning_at (loc, OPT_Wvector_operation_performance,

+	      "vector condition will be expanded piecewise");

+

+  v = VEC_alloc(constructor_elt, gc, nunits);

+  for (i = 0; i < nunits;

+       i++, index = int_const_binop (PLUS_EXPR, index, width))

+    {

+      tree aa, result;

+      tree bb = tree_vec_extract (gsi, inner_type, b, width, index);

+      tree cc = tree_vec_extract (gsi, inner_type, c, width, index);

+      if (a_is_comparison)

+	{

+	  tree aa1 = tree_vec_extract (gsi, comp_inner_type, a1, width, index);

+	  tree aa2 = tree_vec_extract (gsi, comp_inner_type, a2, width, index);

+	  aa = build2 (TREE_CODE (a), cond_type, aa1, aa2);

+	}

+      else

+	aa = tree_vec_extract (gsi, cond_type, a, width, index);

+      result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);

+      constructor_elt ce = {NULL_TREE, result};

+      VEC_quick_push (constructor_elt, v, ce);

+    }

+

+  constr = build_constructor (type, v);

+  gimple_assign_set_rhs_from_tree (gsi, constr);

+  update_stmt (gsi_stmt (*gsi));

+}

+

 static tree
 expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
 			 gimple assign, enum tree_code code)
 {
   enum machine_mode compute_mode = TYPE_MODE (compute_type);
 
   /* If the compute mode is not a vector mode (hence we are not decomposing
      a BLKmode vector to smaller, hardware-supported vectors), we may want
      to expand the operations in parallel.  */
   if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
@@ -1241,20 +1307,25 @@  expand_vector_operations_1 (gimple_stmt_

   code = gimple_assign_rhs_code (stmt);
   rhs_class = get_gimple_rhs_class (code);
   lhs = gimple_assign_lhs (stmt);
 
   if (code == VEC_PERM_EXPR)
     {
       lower_vec_perm (gsi);
       return;
     }
 
+  if (code == VEC_COND_EXPR)

+    {

+      expand_vector_condition (gsi);

+      return;

+    }

   if (rhs_class != GIMPLE_UNARY_RHS && rhs_class != GIMPLE_BINARY_RHS)
     return;
 
   rhs1 = gimple_assign_rhs1 (stmt);
   type = gimple_expr_type (stmt);
   if (rhs_class == GIMPLE_BINARY_RHS)
     rhs2 = gimple_assign_rhs2 (stmt);
 
   if (TREE_CODE (type) != VECTOR_TYPE)
     return;