Patchwork Fold {2, 3, 4, 5} >> 31

login
register
mail settings
Submitter Marc Glisse
Date April 11, 2013, 4:24 p.m.
Message ID <alpine.DEB.2.02.1304111812580.27055@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/235825/
State New
Headers show

Comments

Marc Glisse - April 11, 2013, 4:24 p.m.
Hello,

here is a patch to handle constant folding of mixed vector-integer 
operations. I could have shared the loop with the vector-vector case, but 
that would have meant re-testing if arg2 was a vector at every iteration 
(I can go back to that version if you prefer).

bootstrap+testsuite on x86_64-linux-gnu

2013-04-11  Marc Glisse  <marc.glisse@inria.fr>

gcc/
 	* fold-const.c (const_binop): Handle vector shifts by a scalar.
 	(fold_binary_loc): Call const_binop also for mixed vector-scalar
 	operations.

gcc/testsuite/
 	* gcc.dg/fold-cstvecshift.c: New testcase.
Jakub Jelinek - April 11, 2013, 4:29 p.m.
On Thu, Apr 11, 2013 at 06:24:02PM +0200, Marc Glisse wrote:
> here is a patch to handle constant folding of mixed vector-integer
> operations. I could have shared the loop with the vector-vector
> case, but that would have meant re-testing if arg2 was a vector at
> every iteration (I can go back to that version if you prefer).

Yeah, that is the kind of thinking I had too.

> +  /* Shifts allow a scalar offset for a vector.  */
> +  if (TREE_CODE (arg1) == VECTOR_CST)

I'd prefer && TREE_CODE (arg2) == INTEGER_CST added to the condition
here.

> +    {
> +      tree type = TREE_TYPE (arg1);
> +      int count = TYPE_VECTOR_SUBPARTS (type), i;
> +      tree *elts =  XALLOCAVEC (tree, count);

Please use just one space.

> +
> +      for (i = 0; i < count; i++)
> +	{
> +          tree elem1 = VECTOR_CST_ELT (arg1, i);
> +
> +          elts[i] = const_binop (code, elem1, arg2);
> +
> +          /* It is possible that const_binop cannot handle the given
> +            code and return NULL_TREE */
> +	  if (elts[i] == NULL_TREE)
>              return NULL_TREE;

And please use tabs where possible, instead of 8 spaces.

> --- gcc/testsuite/gcc.dg/fold-cstvecshift.c	(revision 0)
> +++ gcc/testsuite/gcc.dg/fold-cstvecshift.c	(revision 0)
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-ccp1" } */
> +
> +typedef int vec __attribute__ ((vector_size (4 * sizeof (int))));
> +
> +void f (vec *r)
> +{
> +  vec a = { 2, 3, 4, 5 };
> +  *r = (a << 2) >> 1;
> +}
> +
> +/* { dg-final { scan-tree-dump "{ 4, 6, 8, 10 }" "ccp1"} } */
> +/* { dg-final { cleanup-tree-dump "ccp1" } } */

Have you tested the testcase say for -m32 -mno-sse too, to see
if it doesn't fail without HW vector support?
If so, the patch is ok with the above mentioned changes.

	Jakub

Patch

Index: gcc/fold-const.c

===================================================================
--- gcc/fold-const.c	(revision 197797)

+++ gcc/fold-const.c	(working copy)

@@ -1335,34 +1335,56 @@  const_binop (enum tree_code code, tree a

 	  return NULL_TREE;
 	}
 
       if (real && imag)
 	return build_complex (type, real, imag);
     }
 
   if (TREE_CODE (arg1) == VECTOR_CST
       && TREE_CODE (arg2) == VECTOR_CST)
     {
-      tree type = TREE_TYPE(arg1);

+      tree type = TREE_TYPE (arg1);

       int count = TYPE_VECTOR_SUBPARTS (type), i;
       tree *elts =  XALLOCAVEC (tree, count);
 
       for (i = 0; i < count; i++)
 	{
           tree elem1 = VECTOR_CST_ELT (arg1, i);
 	  tree elem2 = VECTOR_CST_ELT (arg2, i);
 
           elts[i] = const_binop (code, elem1, elem2);
 
           /* It is possible that const_binop cannot handle the given
             code and return NULL_TREE */
-          if(elts[i] == NULL_TREE)

+          if (elts[i] == NULL_TREE)

+	    return NULL_TREE;

+	}

+

+      return build_vector (type, elts);

+    }

+

+  /* Shifts allow a scalar offset for a vector.  */

+  if (TREE_CODE (arg1) == VECTOR_CST)

+    {

+      tree type = TREE_TYPE (arg1);

+      int count = TYPE_VECTOR_SUBPARTS (type), i;

+      tree *elts =  XALLOCAVEC (tree, count);

+

+      for (i = 0; i < count; i++)

+	{

+          tree elem1 = VECTOR_CST_ELT (arg1, i);

+

+          elts[i] = const_binop (code, elem1, arg2);

+

+          /* It is possible that const_binop cannot handle the given

+            code and return NULL_TREE */

+	  if (elts[i] == NULL_TREE)

             return NULL_TREE;
 	}
 
       return build_vector (type, elts);
     }
   return NULL_TREE;
 }
 
 /* Create a sizetype INT_CST node with NUMBER sign extended.  KIND
    indicates which particular sizetype to create.  */
@@ -9852,21 +9874,22 @@  fold_binary_loc (location_t loc,

       STRIP_NOPS (arg1);
     }
 
   /* Note that TREE_CONSTANT isn't enough: static var addresses are
      constant but we can't do arithmetic on them.  */
   if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
       || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
       || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST)
       || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST)
       || (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
-      || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST))

+      || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)

+      || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == INTEGER_CST))

     {
       if (kind == tcc_binary)
 	{
 	  /* Make sure type and arg0 have the same saturating flag.  */
 	  gcc_assert (TYPE_SATURATING (type)
 		      == TYPE_SATURATING (TREE_TYPE (arg0)));
 	  tem = const_binop (code, arg0, arg1);
 	}
       else if (kind == tcc_comparison)
 	tem = fold_relational_const (code, type, arg0, arg1);
Index: gcc/testsuite/gcc.dg/fold-cstvecshift.c

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

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

@@ -0,0 +1,13 @@ 

+/* { dg-do compile } */

+/* { dg-options "-O -fdump-tree-ccp1" } */

+

+typedef int vec __attribute__ ((vector_size (4 * sizeof (int))));

+

+void f (vec *r)

+{

+  vec a = { 2, 3, 4, 5 };

+  *r = (a << 2) >> 1;

+}

+

+/* { dg-final { scan-tree-dump "{ 4, 6, 8, 10 }" "ccp1"} } */

+/* { dg-final { cleanup-tree-dump "ccp1" } } */