Hello,

I noticed while writing the patch posted at:
http://gcc.gnu.org/ml/gcc-patches/2012-08/msg01755.html

that fold_ternary_loc sometimes doesn't go all the way for VEC_PERM_EXPR, calling it a second time would fold even more. Fixed by a simple reordering.

(bootstrap and testsuite are ok)

2012-09-01  Marc Glisse  <marc.gli...@inria.fr>

gcc/
        * fold-const.c (fold_ternary_loc): Constant-propagate after
        removing dead operands.

gcc/testsuite/
        * gcc.dg/fold-perm.c: Improve test.

--
Marc Glisse
Index: fold-const.c
===================================================================
--- fold-const.c        (revision 190845)
+++ fold-const.c        (working copy)
@@ -14189,40 +14189,40 @@ fold_ternary_loc (location_t loc, enum t
            }
 
          if (maybe_identity)
            {
              if (all_in_vec0)
                return op0;
              if (all_in_vec1)
                return op1;
            }
 
-         if ((TREE_CODE (arg0) == VECTOR_CST
-              || TREE_CODE (arg0) == CONSTRUCTOR)
-             && (TREE_CODE (arg1) == VECTOR_CST
-                 || TREE_CODE (arg1) == CONSTRUCTOR))
-           {
-             t = fold_vec_perm (type, arg0, arg1, sel);
-             if (t != NULL_TREE)
-               return t;
-           }
-
          if (all_in_vec0)
            op1 = op0;
          else if (all_in_vec1)
            {
              op0 = op1;
              for (i = 0; i < nelts; i++)
                sel[i] -= nelts;
              need_mask_canon = true;
            }
 
+         if ((TREE_CODE (op0) == VECTOR_CST
+              || TREE_CODE (op0) == CONSTRUCTOR)
+             && (TREE_CODE (op1) == VECTOR_CST
+                 || TREE_CODE (op1) == CONSTRUCTOR))
+           {
+             t = fold_vec_perm (type, op0, op1, sel);
+             if (t != NULL_TREE)
+               return t;
+           }
+
          if (op0 == op1 && !single_arg)
            changed = true;
 
          if (need_mask_canon && arg2 == op2)
            {
              tree *tsel = XALLOCAVEC (tree, nelts);
              tree eltype = TREE_TYPE (TREE_TYPE (arg2));
              for (i = 0; i < nelts; i++)
                tsel[i] = build_int_cst (eltype, sel[i]);
              op2 = build_vector (TREE_TYPE (arg2), tsel);
Index: testsuite/gcc.dg/fold-perm.c
===================================================================
--- testsuite/gcc.dg/fold-perm.c        (revision 190845)
+++ testsuite/gcc.dg/fold-perm.c        (working copy)
@@ -1,19 +1,20 @@
 /* { dg-do compile } */
 /* { dg-options "-O -fdump-tree-ccp1" } */
 
 typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
 
-void fun (veci *f, veci *g, veci *h)
+void fun (veci *f, veci *g, veci *h, veci *i)
 {
   veci m = { 7, 7, 4, 6 };
   veci n = { 0, 1, 2, 3 };
   veci p = { 1, 1, 7, 6 };
+  *i = __builtin_shuffle (*i,  p, m);
   *h = __builtin_shuffle (*h, *h, p);
   *g = __builtin_shuffle (*f, *g, m);
   *f = __builtin_shuffle (*f, *g, n);
 }
 
 /* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "ccp1" } } */
 /* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "ccp1" } } */
 /* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "ccp1" } } */
 /* { dg-final { cleanup-tree-dump "ccp1" } } */

Reply via email to