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]

Re: [PATCH] Fold VEC_[LR]SHIFT_EXPR (PR tree-optimization/57051)


On Thu, Apr 25, 2013 at 11:47:02PM +0200, Jakub Jelinek wrote:
> This patch adds folding of constant arguments v>> and v<<, which helps to
> optimize the testcase from the PR back into constant store after vectorized
> loop is unrolled.

As this fixes a regression on the 4.8 branch, I've backported it (and
minimal prerequisite for that) to 4.8 branch too.

As the non-whole vector shifts VECTOR_CST by INTEGER_CST don't have any
testcase showing a regression, I've left those out (trunk has instead
of that else return NULL_TREE; code to handle those).

2013-05-03  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-04-26  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/57051
	* fold-const.c (const_binop): Handle VEC_LSHIFT_EXPR
	and VEC_RSHIFT_EXPR if shift count is a multiple of element
	bitsize.

	2013-04-12  Marc Glisse  <marc.glisse@inria.fr>

	* fold-const.c (fold_binary_loc): Call const_binop also for mixed
	vector-scalar operations.

--- gcc/fold-const.c	(revision 198579)
+++ gcc/fold-const.c	(working copy)
@@ -1366,6 +1366,44 @@ const_binop (enum tree_code code, tree a
 
       return build_vector (type, elts);
     }
+
+  /* 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);
+
+      if (code == VEC_LSHIFT_EXPR
+	  || code == VEC_RSHIFT_EXPR)
+	{
+	  if (!host_integerp (arg2, 1))
+	    return NULL_TREE;
+
+	  unsigned HOST_WIDE_INT shiftc = tree_low_cst (arg2, 1);
+	  unsigned HOST_WIDE_INT outerc = tree_low_cst (TYPE_SIZE (type), 1);
+	  unsigned HOST_WIDE_INT innerc
+	    = tree_low_cst (TYPE_SIZE (TREE_TYPE (type)), 1);
+	  if (shiftc >= outerc || (shiftc % innerc) != 0)
+	    return NULL_TREE;
+	  int offset = shiftc / innerc;
+	  if (code == VEC_LSHIFT_EXPR)
+	    offset = -offset;
+	  tree zero = build_zero_cst (TREE_TYPE (type));
+	  for (i = 0; i < count; i++)
+	    {
+	      if (i + offset < 0 || i + offset >= count)
+		elts[i] = zero;
+	      else
+		elts[i] = VECTOR_CST_ELT (arg1, i + offset);
+	    }
+	}
+      else
+	return NULL_TREE;
+
+      return build_vector (type, elts);
+    }
   return NULL_TREE;
 }
 
@@ -9862,7 +9900,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)
 	{


	Jakub


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