fold-const.c (const_binop): Handle vector shifts by a scalar.
authorMarc Glisse <marc.glisse@inria.fr>
Fri, 12 Apr 2013 07:40:37 +0000 (09:40 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Fri, 12 Apr 2013 07:40:37 +0000 (07:40 +0000)
2013-04-12  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.

From-SVN: r197843

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/fold-cstvecshift.c [new file with mode: 0644]

index 9cc89e5..adb3981 100644 (file)
@@ -1,3 +1,9 @@
+2013-04-12  Marc Glisse  <marc.glisse@inria.fr>
+
+       * fold-const.c (const_binop): Handle vector shifts by a scalar.
+       (fold_binary_loc): Call const_binop also for mixed vector-scalar
+       operations.
+
 2013-04-12  Manuel López-Ibáñez  <manu@gcc.gnu.org>
            Jakub Jelinek  <jakub@redhat.com>
 
index 467b6d6..e8187cb 100644 (file)
@@ -1342,21 +1342,44 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
   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;
+       }
+
+      return build_vector (type, elts);
+    }
 
-          /* It is possible that const_binop cannot handle the given
-            code and return NULL_TREE */
-          if(elts[i] == NULL_TREE)
-            return NULL_TREE;
+  /* 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);
@@ -9859,7 +9882,8 @@ fold_binary_loc (location_t loc,
       || (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)
        {
index 4ee12e8..ec11002 100644 (file)
@@ -1,3 +1,7 @@
+2013-04-12  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/fold-cstvecshift.c: New testcase.
+
 2013-04-11   Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>
 
        * gcc.target/aarch64/negs.c: New.
diff --git a/gcc/testsuite/gcc.dg/fold-cstvecshift.c b/gcc/testsuite/gcc.dg/fold-cstvecshift.c
new file mode 100644 (file)
index 0000000..51f42d4
--- /dev/null
@@ -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" } } */