Message ID | 20120928113126.GC1787@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Fri, Sep 28, 2012 at 1:31 PM, Jakub Jelinek <jakub@redhat.com> wrote: > 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? Ok. Thanks, Richard. > 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
--- 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"