This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fold VEC_[LR]SHIFT_EXPR (PR tree-optimization/57051)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 3 May 2013 15:18:29 +0200
- Subject: Re: [PATCH] Fold VEC_[LR]SHIFT_EXPR (PR tree-optimization/57051)
- References: <20130425214702 dot GJ28963 at tucnak dot redhat dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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