On Thu, 11 Apr 2013, Jakub Jelinek wrote:
On Thu, Apr 11, 2013 at 06:24:02PM +0200, Marc Glisse wrote:
here is a patch to handle constant folding of mixed vector-integer
operations. I could have shared the loop with the vector-vector
case, but that would have meant re-testing if arg2 was a vector at
every iteration (I can go back to that version if you prefer).
Yeah, that is the kind of thinking I had too.
+ /* Shifts allow a scalar offset for a vector. */
+ if (TREE_CODE (arg1) == VECTOR_CST)
I'd prefer && TREE_CODE (arg2) == INTEGER_CST added to the condition
here.
:-) I added and removed it a few times before deciding.
Please use just one space.
And please use tabs where possible, instead of 8 spaces.
Argh, I fixed a couple formatting issues before copy-pasting, but I had
missed quite a few.
Have you tested the testcase say for -m32 -mno-sse too, to see
if it doesn't fail without HW vector support?
Yes.
If so, the patch is ok with the above mentioned changes.
Ok, I'll retest during the night.
--
Marc Glisse
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 197819)
+++ gcc/fold-const.c (working copy)
@@ -1335,35 +1335,58 @@ const_binop (enum tree_code code, tree a
return NULL_TREE;
}
if (real && imag)
return build_complex (type, real, imag);
}
if (TREE_CODE (arg1) == VECTOR_CST
&& TREE_CODE (arg2) == VECTOR_CST)
{
- tree type = TREE_TYPE(arg1);
+ tree type = TREE_TYPE (arg1);
int count = TYPE_VECTOR_SUBPARTS (type), i;
- tree *elts = XALLOCAVEC (tree, count);
+ tree *elts = XALLOCAVEC (tree, count);
for (i = 0; i < count; i++)
{
- tree elem1 = VECTOR_CST_ELT (arg1, i);
+ tree elem1 = VECTOR_CST_ELT (arg1, i);
tree elem2 = VECTOR_CST_ELT (arg2, i);
- elts[i] = const_binop (code, elem1, elem2);
+ elts[i] = const_binop (code, elem1, elem2);
- /* It is possible that const_binop cannot handle the given
- code and return NULL_TREE */
- if(elts[i] == NULL_TREE)
- return NULL_TREE;
+ /* It is possible that const_binop cannot handle the given
+ code and return NULL_TREE */
+ if (elts[i] == NULL_TREE)
+ return NULL_TREE;
+ }
+
+ 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);
+
+ for (i = 0; i < count; i++)
+ {
+ tree elem1 = VECTOR_CST_ELT (arg1, i);
+
+ elts[i] = const_binop (code, elem1, arg2);
+
+ /* It is possible that const_binop cannot handle the given
+ code and return NULL_TREE */
+ if (elts[i] == NULL_TREE)
+ return NULL_TREE;
}
return build_vector (type, elts);
}
return NULL_TREE;
}
/* Create a sizetype INT_CST node with NUMBER sign extended. KIND
indicates which particular sizetype to create. */
@@ -9852,21 +9875,22 @@ fold_binary_loc (location_t loc,
STRIP_NOPS (arg1);
}
/* Note that TREE_CONSTANT isn't enough: static var addresses are
constant but we can't do arithmetic on them. */
if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
|| (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
|| (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)
{
/* Make sure type and arg0 have the same saturating flag. */
gcc_assert (TYPE_SATURATING (type)
== TYPE_SATURATING (TREE_TYPE (arg0)));
tem = const_binop (code, arg0, arg1);
}
else if (kind == tcc_comparison)
tem = fold_relational_const (code, type, arg0, arg1);
Index: gcc/testsuite/gcc.dg/fold-cstvecshift.c
===================================================================
--- gcc/testsuite/gcc.dg/fold-cstvecshift.c (revision 0)
+++ gcc/testsuite/gcc.dg/fold-cstvecshift.c (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+typedef int vec __attribute__ ((vector_size (4 * sizeof (int))));
+
+void f (vec *r)
+{
+ vec a = { 2, 3, 4, 5 };
+ *r = (a << 2) >> 1;
+}
+
+/* { dg-final { scan-tree-dump "{ 4, 6, 8, 10 }" "ccp1"} } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */
Property changes on: gcc/testsuite/gcc.dg/fold-cstvecshift.c
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision URL
Added: svn:eol-style
+ native