Hello,this patch fixes several ICEs when using constexpr SIMD vectors. Support for subscripting is still missing though, which is why I am not adding some static_asserts to the testcase. I don't use build_vector_from_ctor because it doesn't check for non-constant elements and doesn't handle vectors in a constructor (the middle-end produces those, and I expect the front-ends will too eventually).
Bootstrap+testsuite on x86_64-linux-gnu. 2012-11-29 Marc Glisse <marc.gli...@inria.fr> PR c++/53094 gcc/ * fold-const.c (fold): Replace a CONSTRUCTOR with a VECTOR_CST. gcc/cp/ * cvt.c (ocp_convert): Call convert_to_vector. gcc/testsuite/ * g++.dg/ext/vector20.C: New testcase. -- Marc Glisse
Index: gcc/cp/cvt.c =================================================================== --- gcc/cp/cvt.c (revision 193922) +++ gcc/cp/cvt.c (working copy) @@ -683,20 +683,22 @@ ocp_convert (tree type, tree expr, int c might be expected, since if one of the types is a typedef; the comparison in fold is just equality of pointers, not a call to comptypes. We don't call fold in this case because that can result in infinite recursion; fold will call convert, which will call ocp_convert, etc. */ return e; /* For complex data types, we need to perform componentwise conversion. */ else if (TREE_CODE (type) == COMPLEX_TYPE) return fold_if_not_in_template (convert_to_complex (type, e)); + else if (TREE_CODE (type) == VECTOR_TYPE) + return fold_if_not_in_template (convert_to_vector (type, e)); else if (TREE_CODE (e) == TARGET_EXPR) { /* Don't build a NOP_EXPR of class type. Instead, change the type of the temporary. */ TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type; return e; } else { /* We shouldn't be treating objects of ADDRESSABLE type as Index: gcc/testsuite/g++.dg/ext/vector20.C =================================================================== --- gcc/testsuite/g++.dg/ext/vector20.C (revision 0) +++ gcc/testsuite/g++.dg/ext/vector20.C (revision 0) @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c++11" } */ + +typedef long vec __attribute__((vector_size (2 * sizeof (long)))); +constexpr vec v = { 3, 4 }; +constexpr vec s = v + v; +constexpr vec w = __builtin_shuffle (v, v); Property changes on: gcc/testsuite/g++.dg/ext/vector20.C ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision URL Added: svn:eol-style + native Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 193922) +++ gcc/fold-const.c (working copy) @@ -14380,20 +14380,49 @@ fold (tree expr) && tree_int_cst_lt (op1, TREE_OPERAND (index, 0))) end = middle; else return (*elts)[middle].value; } } return t; } + /* Return a VECTOR_CST if possible. */ + case CONSTRUCTOR: + { + tree type = TREE_TYPE (t); + if (TREE_CODE (type) != VECTOR_TYPE) + return t; + + tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); + unsigned HOST_WIDE_INT idx, pos = 0; + tree value; + + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, value) + { + if (!CONSTANT_CLASS_P (value)) + return t; + if (TREE_CODE (value) == VECTOR_CST) + { + for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i) + vec[pos++] = VECTOR_CST_ELT (value, i); + } + else + vec[pos++] = value; + } + for (; pos < TYPE_VECTOR_SUBPARTS (type); ++pos) + vec[pos] = build_zero_cst (TREE_TYPE (type)); + + return build_vector (type, vec); + } + case CONST_DECL: return fold (DECL_INITIAL (t)); default: return t; } /* switch (code) */ } #ifdef ENABLE_FOLD_CHECKING #undef fold