This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix up vector CONSTRUCTOR handling (PR tree-optimization/54713)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 28 Sep 2012 13:31:26 +0200
- Subject: [PATCH] Fix up vector CONSTRUCTOR handling (PR tree-optimization/54713)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As discussed in the PR, tree-vect-generic.c sometimes creates CONSTRUCTORs
with vector elements to build up larger vectors from vectors supported by
HW. This patch teaches fold-const to bail up on those. Vector CONSTRUCTOR
verification changes and assorted fixes have been separated from the patch
and will be posted probably next week.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2012-09-28 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/54713
* fold-const.c (vec_cst_ctor_to_array): Give up if vector CONSTRUCTOR
has vector elements.
(fold_ternary_loc) <case BIT_FIELD_REF>: Likewise.
* tree-vect-generic.c (vector_element): Don't rely on CONSTRUCTOR elts
indexes. Use BIT_FIELD_REF if CONSTRUCTOR has vector elements.
(lower_vec_perm): Use NULL_TREE CONSTRUCTOR indexes.
* gcc.c-torture/compile/pr54713-1.c: New test.
* gcc.c-torture/compile/pr54713-2.c: New test.
* gcc.c-torture/compile/pr54713-3.c: New test.
--- gcc/fold-const.c.jj 2012-09-25 11:59:43.000000000 +0200
+++ gcc/fold-const.c 2012-09-26 13:14:05.639000395 +0200
@@ -9559,7 +9559,7 @@ vec_cst_ctor_to_array (tree arg, tree *e
constructor_elt *elt;
FOR_EACH_VEC_ELT (constructor_elt, CONSTRUCTOR_ELTS (arg), i, elt)
- if (i >= nelts)
+ if (i >= nelts || TREE_CODE (TREE_TYPE (elt->value)) == VECTOR_TYPE)
return false;
else
elts[i] = elt->value;
@@ -14030,22 +14030,35 @@ fold_ternary_loc (location_t loc, enum t
unsigned i;
if (CONSTRUCTOR_NELTS (arg0) == 0)
return build_constructor (type, NULL);
- vals = VEC_alloc (constructor_elt, gc, n);
- for (i = 0; i < n && idx + i < CONSTRUCTOR_NELTS (arg0);
- ++i)
- CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
- CONSTRUCTOR_ELT
- (arg0, idx + i)->value);
- return build_constructor (type, vals);
+ if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0,
+ 0)->value))
+ != VECTOR_TYPE)
+ {
+ vals = VEC_alloc (constructor_elt, gc, n);
+ for (i = 0;
+ i < n && idx + i < CONSTRUCTOR_NELTS (arg0);
+ ++i)
+ CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
+ CONSTRUCTOR_ELT
+ (arg0, idx + i)->value);
+ return build_constructor (type, vals);
+ }
}
}
else if (n == 1)
{
if (TREE_CODE (arg0) == VECTOR_CST)
return VECTOR_CST_ELT (arg0, idx);
- else if (idx < CONSTRUCTOR_NELTS (arg0))
- return CONSTRUCTOR_ELT (arg0, idx)->value;
- return build_zero_cst (type);
+ else if (CONSTRUCTOR_NELTS (arg0) == 0)
+ return build_zero_cst (type);
+ else if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0,
+ 0)->value))
+ != VECTOR_TYPE)
+ {
+ if (idx < CONSTRUCTOR_NELTS (arg0))
+ return CONSTRUCTOR_ELT (arg0, idx)->value;
+ return build_zero_cst (type);
+ }
}
}
}
--- gcc/tree-vect-generic.c.jj 2012-09-18 12:14:48.000000000 +0200
+++ gcc/tree-vect-generic.c 2012-09-26 14:23:40.742171292 +0200
@@ -1050,14 +1050,13 @@ vector_element (gimple_stmt_iterator *gs
if (TREE_CODE (vect) == VECTOR_CST)
return VECTOR_CST_ELT (vect, index);
- else if (TREE_CODE (vect) == CONSTRUCTOR)
+ else if (TREE_CODE (vect) == CONSTRUCTOR
+ && (CONSTRUCTOR_NELTS (vect) == 0
+ || TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (vect, 0)->value))
+ != VECTOR_TYPE))
{
- unsigned i;
- tree elt_i, elt_v;
-
- FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (vect), i, elt_i, elt_v)
- if (operand_equal_p (elt_i, idx, 0))
- return elt_v;
+ if (index < CONSTRUCTOR_NELTS (vect))
+ return CONSTRUCTOR_ELT (vect, index)->value;
return build_zero_cst (vect_elt_type);
}
else
@@ -1215,7 +1214,7 @@ lower_vec_perm (gimple_stmt_iterator *gs
t = v0_val;
}
- CONSTRUCTOR_APPEND_ELT (v, si, t);
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
}
constr = build_constructor (vect_type, v);
--- gcc/testsuite/gcc.c-torture/compile/pr54713-1.c.jj 2012-09-26 14:25:00.560733901 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr54713-1.c 2012-09-26 12:10:09.000000000 +0200
@@ -0,0 +1,70 @@
+/* PR tree-optimization/54713 */
+
+#ifndef N
+#define N 8
+#define ONE 1, 1, 1, 1, 1, 1, 1, 1
+#define ONEU 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U
+#endif
+
+typedef int V __attribute__((vector_size (N * sizeof (int))));
+typedef unsigned int W __attribute__((vector_size (N * sizeof (int))));
+
+void
+f1 (V *p)
+{
+ *p = (*p & ((V) { ONE })) ^ ((V) { ONE});
+}
+
+void
+f2 (V *p)
+{
+ *p = (*p ^ ((V) { ONE })) & ((V) { ONE});
+}
+
+void
+f3 (V *p)
+{
+ *p = (~*p) & ((V) { ONE });
+}
+
+void
+f4 (V *p, V *q)
+{
+ *p = (*p ^ *q) == *q;
+}
+
+void
+f5 (V *p, V *q)
+{
+ *p = (*p ^ *q) == *p;
+}
+
+void
+f6 (V *p, V *q, V *r)
+{
+ *p = (*p & *r) == (*q & *r);
+}
+
+void
+f7 (V *p, V *q, V *r)
+{
+ *p = (*p & *r) == (*r & *q);
+}
+
+void
+f8 (V *p, V *q, V *r)
+{
+ *p = (*r & *p) == (*q & *r);
+}
+
+void
+f9 (V *p, V *q, V *r)
+{
+ *p = (*r & *p) == (*r & *q);
+}
+
+void
+f10 (W *p, W *q)
+{
+ *p = *p < (((const W) { ONEU }) << *q);
+}
--- gcc/testsuite/gcc.c-torture/compile/pr54713-2.c.jj 2012-09-26 14:25:03.273719043 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr54713-2.c 2012-09-26 12:11:40.000000000 +0200
@@ -0,0 +1,7 @@
+/* PR tree-optimization/54713 */
+
+#define N 16
+#define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+#define ONEU 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U
+
+#include "pr54713-1.c"
--- gcc/testsuite/gcc.c-torture/compile/pr54713-3.c.jj 2012-09-26 14:25:06.202702978 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr54713-3.c 2012-09-26 12:11:31.000000000 +0200
@@ -0,0 +1,9 @@
+/* PR tree-optimization/54713 */
+
+#define N 32
+#define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+#define ONEU 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, \
+ 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U
+
+#include "pr54713-1.c"
Jakub