Patchwork constexpr vector operations

login
register
mail settings
Submitter Marc Glisse
Date Nov. 29, 2012, 1:16 p.m.
Message ID <alpine.DEB.2.02.1211291354080.3205@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/202741/
State New
Headers show

Comments

Marc Glisse - Nov. 29, 2012, 1:16 p.m.
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.glisse@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.
Jason Merrill - Nov. 29, 2012, 3:18 p.m.
OK.

Jason

Patch

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