re PR tree-optimization/56790 (VEC_COND_EXPR not constant folded)
authorMarc Glisse <marc.glisse@inria.fr>
Wed, 3 Apr 2013 09:49:44 +0000 (11:49 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Wed, 3 Apr 2013 09:49:44 +0000 (09:49 +0000)
2013-04-03  Marc Glisse  <marc.glisse@inria.fr>

PR tree-optimization/56790
gcc/
* fold-const.c (fold_ternary_loc) <VEC_COND_EXPR>: Add constant folding.

gcc/testsuite/
* g++.dg/ext/pr56790-1.C: New testcase.

From-SVN: r197395

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/pr56790-1.C [new file with mode: 0644]

index 33773594e296fe1cf42ff79b2d6320dbe3a4c450..512fe4abbaacaf756a890f234f73f77b46bfae64 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR tree-optimization/56790
+       * fold-const.c (fold_ternary_loc) <VEC_COND_EXPR>: Add constant folding.
+
 2013-04-03  Marc Glisse  <marc.glisse@inria.fr>
 
        * simplify-rtx.c (simplify_binary_operation_1) <VEC_SELECT>:
index 905661cf7e6dfc8329b2cd441bc2c84a465c8e95..dcf7aa0d6a5040ec24a29eb13fd154b378381a92 100644 (file)
@@ -13924,6 +13924,29 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
            return pedantic_omit_one_operand_loc (loc, type, arg1, arg2);
          if (integer_zerop (arg0))
            return pedantic_omit_one_operand_loc (loc, type, arg2, arg1);
+
+         if ((TREE_CODE (arg1) == VECTOR_CST
+              || TREE_CODE (arg1) == CONSTRUCTOR)
+             && (TREE_CODE (arg2) == VECTOR_CST
+                 || TREE_CODE (arg2) == CONSTRUCTOR))
+           {
+             unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+             unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
+             gcc_assert (nelts == VECTOR_CST_NELTS (arg0));
+             for (i = 0; i < nelts; i++)
+               {
+                 tree val = VECTOR_CST_ELT (arg0, i);
+                 if (integer_all_onesp (val))
+                   sel[i] = i;
+                 else if (integer_zerop (val))
+                   sel[i] = nelts + i;
+                 else /* Currently unreachable.  */
+                   return NULL_TREE;
+               }
+             tree t = fold_vec_perm (type, arg1, arg2, sel);
+             if (t != NULL_TREE)
+               return t;
+           }
        }
 
       if (operand_equal_p (arg1, op2, 0))
index 9ce315c5cf455877d79ca2fbe42126fd363e19ee..b147235b908e9ae3eceb04de291c0c969305a844 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR tree-optimization/56790
+       * g++.dg/ext/pr56790-1.C: New testcase.
+
 2013-04-03  Marc Glisse  <marc.glisse@inria.fr>
 
        * gcc.target/i386/merge-1.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/ext/pr56790-1.C b/gcc/testsuite/g++.dg/ext/pr56790-1.C
new file mode 100644 (file)
index 0000000..84feca1
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ccp1" } */
+
+typedef long vec __attribute__ ((vector_size (2 * sizeof (long))));
+
+vec f (void)
+{
+  vec a = {  5,  7 };
+  vec b = { 11, 13 };
+  vec m = { -1,  0 };
+  return m ? a : b;
+}
+
+/* { dg-final { scan-tree-dump "{ 5, 13 }" "ccp1" } } */
+/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "ccp1" } } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */