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

Reply via email to