Patchwork [C++] Handle VECTOR_CSTs in adjust_temp_type (PR c++/55573)

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 6, 2012, 7:16 a.m.
Message ID <20121206071640.GF2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/204160/
State New
Headers show

Comments

Jakub Jelinek - Dec. 6, 2012, 7:16 a.m.
Hi!

With Marc's recent changes to fold vector CONSTRUCTORs into VECTOR_CSTs
if possible, we now ICE in adjust_temp_type, because the type of VECTOR_CST
is not SCALAR_TYPE_P.  Either we can handle VECTOR_CSTs directly
(in that case ignore_overflows is also called on each VECTOR_CST constant,
but not sure if that is needed), as done in the patch below, or
Marc has an alternative patch to just change the assert into
gcc_assert (scalarish_type_p);
Which way do you prefer?

This one has been bootstrapped/regtested on x86_64-linux and i686-linux.

BTW, the PR and the referenced PR contains some other patches, e.g.
cp_tree_equal not handling VECTOR_CSTs.  For that it is a similar question,
either VECTOR_CSTs can be handled there using operand_equal_p, or
by calling cp_tree_equal on the VECTOR_CST elements.

2012-12-06  Jakub Jelinek  <jakub@redhat.com>

	PR c++/55573
	* semantics.c (adjust_temp_type): Handle VECTOR_CST.

	* g++.dg/cpp0x/constexpr-55573.C: New test.


	Jakub
Jason Merrill - Dec. 6, 2012, 2:13 p.m.
On 12/06/2012 02:16 AM, Jakub Jelinek wrote:
> With Marc's recent changes to fold vector CONSTRUCTORs into VECTOR_CSTs
> if possible, we now ICE in adjust_temp_type, because the type of VECTOR_CST
> is not SCALAR_TYPE_P.  Either we can handle VECTOR_CSTs directly
> (in that case ignore_overflows is also called on each VECTOR_CST constant,
> but not sure if that is needed), as done in the patch below, or
> Marc has an alternative patch to just change the assert into
> gcc_assert (scalarish_type_p);
> Which way do you prefer?

If Marc's patch works, let's go with that.

> BTW, the PR and the referenced PR contains some other patches, e.g.
> cp_tree_equal not handling VECTOR_CSTs.  For that it is a similar question,
> either VECTOR_CSTs can be handled there using operand_equal_p, or
> by calling cp_tree_equal on the VECTOR_CST elements.

Let's go with the operand_equal_p option; less code duplication is good.

Jason

Patch

--- gcc/cp/semantics.c.jj	2012-11-23 00:14:40.000000000 +0100
+++ gcc/cp/semantics.c	2012-12-03 14:02:54.407690163 +0100
@@ -6451,6 +6451,14 @@  adjust_temp_type (tree type, tree temp)
   /* Avoid wrapping an aggregate value in a NOP_EXPR.  */
   if (TREE_CODE (temp) == CONSTRUCTOR)
     return build_constructor (type, CONSTRUCTOR_ELTS (temp));
+  if (TREE_CODE (temp) == VECTOR_CST)
+    {
+      int i, count = TYPE_VECTOR_SUBPARTS (type);
+      tree *vec = XALLOCAVEC (tree, count);
+      for (i = 0; i < count; i++)
+	vec[i] = cp_fold_convert (TREE_TYPE (type), VECTOR_CST_ELT (temp, i));
+      return build_vector (type, vec);
+    }
   gcc_assert (SCALAR_TYPE_P (type));
   return cp_fold_convert (type, temp);
 }
--- gcc/testsuite/g++.dg/cpp0x/constexpr-55573.C.jj	2012-12-03 14:21:05.367303150 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-55573.C	2012-12-03 14:19:42.000000000 +0100
@@ -0,0 +1,22 @@ 
+// PR c++/55573
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+
+template <typename T, int N>
+struct ExtVecTraits {
+  typedef T __attribute__((vector_size (N * sizeof (T)))) type;
+};
+
+template <typename T>
+using Vec4 = typename ExtVecTraits<T,4>::type;
+
+template <typename T>
+struct Rot3
+{
+  typedef Vec4<T> Vec;
+  Vec axis[3];
+  constexpr Rot3 (Vec4<T> ix, Vec4<T> iy, Vec4<T> iz) : axis {ix, iy, iz} {}
+};
+
+typedef Vec4<float> Vec;
+Rot3<float> r2 ((Vec) {0, 1, 0, 0}, (Vec){0, 0, 1, 0}, (Vec){1, 0, 0, 0});