2009-05-26 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 May 2009 11:41:34 +0000 (11:41 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 May 2009 11:41:34 +0000 (11:41 +0000)
PR middle-end/40252
* fold-const.c (fold_binary): Use the correct types for building
rotates.

* gcc.c-torture/compile/pr40252.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147868 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/tree-ssa-ccp.c

index d2b0362..58db4fa 100644 (file)
@@ -1,5 +1,12 @@
 2009-05-26  Richard Guenther  <rguenther@suse.de>
 
+       PR tree-optimization/40122
+       * tree-ssa-ccp.c (ccp_fold): Fold vector CONSTRUCTORs to
+       VECTOR_CSTs if possible.
+       (fold_gimple_assign): Likewise.
+
+2009-05-26  Richard Guenther  <rguenther@suse.de>
+
        PR middle-end/40252
        * fold-const.c (fold_binary): Use the correct types for building
        rotates.
index c331619..fb6eb4d 100644 (file)
@@ -958,6 +958,30 @@ ccp_fold (gimple stmt)
                        }
                    }
                }
+             else if (TREE_CODE (rhs) == CONSTRUCTOR
+                      && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
+                      && (CONSTRUCTOR_NELTS (rhs)
+                          == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
+               {
+                 unsigned i;
+                 tree val, list;
+
+                 list = NULL_TREE;
+                 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
+                   {
+                     if (TREE_CODE (val) == SSA_NAME
+                         && get_value (val)->lattice_val == CONSTANT)
+                       val = get_value (val)->value;
+                     if (TREE_CODE (val) == INTEGER_CST
+                         || TREE_CODE (val) == REAL_CST
+                         || TREE_CODE (val) == FIXED_CST)
+                       list = tree_cons (NULL_TREE, val, list);
+                     else
+                       return NULL_TREE;
+                   }
+
+                 return build_vector (TREE_TYPE (rhs), nreverse (list));
+               }
 
               if (kind == tcc_reference)
                {
@@ -2654,6 +2678,25 @@ fold_gimple_assign (gimple_stmt_iterator *si)
                                     build_fold_addr_expr (tem));
          }
 
+       else if (TREE_CODE (rhs) == CONSTRUCTOR
+                && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
+                && (CONSTRUCTOR_NELTS (rhs)
+                    == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
+         {
+           /* Fold a constant vector CONSTRUCTOR to VECTOR_CST.  */
+           unsigned i;
+           tree val;
+
+           FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
+             if (TREE_CODE (val) != INTEGER_CST
+                 && TREE_CODE (val) != REAL_CST
+                 && TREE_CODE (val) != FIXED_CST)
+               return NULL_TREE;
+
+           return build_vector_from_ctor (TREE_TYPE (rhs),
+                                          CONSTRUCTOR_ELTS (rhs));
+         }
+
         /* If we couldn't fold the RHS, hand over to the generic
            fold routines.  */
         if (result == NULL_TREE)