Patchwork Fold VEC_[LR]SHIFT_EXPR (PR tree-optimization/57051)

login
register
mail settings
Submitter Jakub Jelinek
Date May 3, 2013, 1:18 p.m.
Message ID <20130503131829.GC28963@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/241310/
State New
Headers show

Comments

Jakub Jelinek - May 3, 2013, 1:18 p.m.
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.



	Jakub
Mikael Pettersson - May 16, 2013, 5:59 p.m.
Jakub Jelinek writes:
 > 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.

Unfortunately this patch makes gcc.dg/vect/no-scevccp-outer-{7,13}.c fail
on powerpc64-linux:

+FAIL: gcc.dg/vect/no-scevccp-outer-13.c execution test
+FAIL: gcc.dg/vect/no-scevccp-outer-7.c execution test

which is a regression from 4.8-20130502.  Reverting r198580 fixes it.

The same FAILs also occur on trunk.

/Mikael

Patch

--- 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)
 	{