On Thu, 11 Apr 2013, Jakub Jelinek wrote:

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.

:-) I added and removed it a few times before deciding.

Please use just one space.
And please use tabs where possible, instead of 8 spaces.

Argh, I fixed a couple formatting issues before copy-pasting, but I had missed quite a few.

Have you tested the testcase say for -m32 -mno-sse too, to see
if it doesn't fail without HW vector support?

Yes.

If so, the patch is ok with the above mentioned changes.

Ok, I'll retest during the night.

--
Marc Glisse
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 197819)
+++ gcc/fold-const.c    (working copy)
@@ -1335,35 +1335,58 @@ 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);
+      tree *elts = XALLOCAVEC (tree, count);
 
       for (i = 0; i < count; i++)
        {
-          tree elem1 = VECTOR_CST_ELT (arg1, i);
+         tree elem1 = VECTOR_CST_ELT (arg1, i);
          tree elem2 = VECTOR_CST_ELT (arg2, i);
 
-          elts[i] = const_binop (code, elem1, elem2);
+         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)
-            return NULL_TREE;
+         /* 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);
+    }
+
+  /* Shifts allow a scalar offset for a vector.  */
+  if (TREE_CODE (arg1) == VECTOR_CST
+      && TREE_CODE (arg2) == INTEGER_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 +9875,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" } } */

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

Reply via email to