This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Constant folding of VEC_COND_EXPR


Hello,

this adds constant folding of VEC_COND_EXPR at the tree level by forwarding to the VEC_PERM_EXPR code (a merge is a special case of a permutation). The CONSTRUCTOR case may be unreachable for now (it will probably need an extra piece of code in tree-ssa-forwprop.c), but it seems better to add it at the same time.

bootstrap+testsuite on x86_64-linux-gnu.

2013-03-31  Marc Glisse  <marc.glisse@inria.fr>

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

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

--
Marc Glisse
Index: gcc/testsuite/g++.dg/ext/pr56790-1.C
===================================================================
--- gcc/testsuite/g++.dg/ext/pr56790-1.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/pr56790-1.C	(revision 0)
@@ -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" } } */

Property changes on: gcc/testsuite/g++.dg/ext/pr56790-1.C
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision URL
Added: svn:eol-style
   + native

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 197284)
+++ gcc/fold-const.c	(working copy)
@@ -13917,20 +13917,43 @@ fold_ternary_loc (location_t loc, enum t
                   || VOID_TYPE_P (type)))
 	    return pedantic_non_lvalue_loc (loc, tem);
 	  return NULL_TREE;
 	}
       else if (TREE_CODE (arg0) == VECTOR_CST)
 	{
 	  if (integer_all_onesp (arg0))
 	    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
+		    gcc_unreachable ();
+		}
+	      tree t = fold_vec_perm (type, arg1, arg2, sel);
+	      if (t != NULL_TREE)
+		return t;
+	    }
 	}
 
       if (operand_equal_p (arg1, op2, 0))
 	return pedantic_omit_one_operand_loc (loc, type, arg1, arg0);
 
       /* If we have A op B ? A : C, we may be able to convert this to a
 	 simpler expression, depending on the operation and the values
 	 of B and C.  Signed zeros prevent all of these transformations,
 	 for reasons given above each one.
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]