public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
@ 2012-06-18 13:32 Ramana Radhakrishnan
  2012-06-22  9:23 ` Ramana Radhakrishnan
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Ramana Radhakrishnan @ 2012-06-18 13:32 UTC (permalink / raw)
  To: gcc-patches; +Cc: Patch Tracking, Jason Merrill, Marc Glisse

[-- Attachment #1: Type: text/plain, Size: 1871 bytes --]

Hi,

This patch following on from the fix for turning on __builtin_shuffle
for c++ , enables folding of vec_perm_exprs in the front-end for
constexpr and constructor style values.  I was originally going to go
with Marc's patch but then took a look at what it would take to
support this properly which appeared to me to be just calling fold
with the right parameters.

With simple tests based on variations from c-c++-common/vshuf*.c using
constexpr execution tests appear to pass - There is still an issue
with the compiler giving an error on seeing a subscript operation with
a __builtin_shuffle - I'm going to let that one for someone else to
pick up because I don't have the time to pick this up right at this
minute and the fact is that folks could use an extra vector for the
time being.

Regression tested with a bootstrap and testrun on powerpc /
x86_64-linux-gnu and cross-tested on arm-linux-gnueabi

Thoughts  ?

regards,
Ramana

cp/

	PR C++/51033
	* semantics.c (constexpr_call): Fix typo in comment.
	(cxx_eval_vec_perm_expr): New.
	(cxx_eval_constant_expression): Fold VEC_PERM_EXPRs.

testsuite/


	* g++.dg/torture/vshuf-16.inc: New test.
	* g++.dg/torture/vshuf-2.inc: New test.
	* g++.dg/torture/vshuf-4.inc: New test.
	* g++.dg/torture/vshuf-8.inc: New test.
	* g++.dg/torture/vshuf-main.inc: New test.
	* g++.dg/torture/vshuf-v16hi.C: New test.
	* g++.dg/torture/vshuf-v16qi.C: New test.
	* g++.dg/torture/vshuf-v2df.C: New test.
	* g++.dg/torture/vshuf-v2di.C: New test.
	* g++.dg/torture/vshuf-v2sf.C: New test.
	* g++.dg/torture/vshuf-v2si.C: New test.
	* g++.dg/torture/vshuf-v4df.C: New test.
	* g++.dg/torture/vshuf-v4di.C: New test.
	* g++.dg/torture/vshuf-v4sf.C: New test.
	* g++.dg/torture/vshuf-v4si.C: New test.
	* g++.dg/torture/vshuf-v8hi.C: New test.
	* g++.dg/torture/vshuf-v8qi.C: New test.
	* g++.dg/torture/vshuf-v8si.C: New test.

[-- Attachment #2: constexpr-vshuf.patch --]
[-- Type: application/octet-stream, Size: 19486 bytes --]

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ee41861..6036a84 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6212,7 +6212,7 @@ explain_invalid_constexpr_fn (tree fun)
 typedef struct GTY(()) constexpr_call {
   /* Description of the constexpr function definition.  */
   constexpr_fundef *fundef;
-  /* Parameter bindings enironment.  A TREE_LIST where each TREE_PURPOSE
+  /* Parameter bindings environment.  A TREE_LIST where each TREE_PURPOSE
      is a parameter _DECL and the TREE_VALUE is the value of the parameter.
      Note: This arrangement is made to accomodate the use of
      iterative_hash_template_arg (see pt.c).  If you change this
@@ -6236,6 +6236,9 @@ static GTY ((param_is (constexpr_call))) htab_t constexpr_call_table;
 
 static tree cxx_eval_constant_expression (const constexpr_call *, tree,
 					  bool, bool, bool *);
+static tree cxx_eval_vec_perm_expr (const constexpr_call, tree, bool, bool,
+				    bool *);
+
 
 /* Compute a hash value for a constexpr call representation.  */
 
@@ -7492,6 +7495,40 @@ non_const_var_error (tree r)
     }
 }
 
+/* Evaluate VEC_PERM_EXPR (v1, v2, mask).  */
+static tree
+cxx_eval_vec_perm_expr (const constexpr_call *call, tree t, 
+			bool allow_non_constant, bool addr,
+			bool * non_constant_p)
+{
+  int i;
+  tree args[3];
+  tree val;
+  tree elttype = TREE_TYPE (t);
+  location_t loc = EXPR_LOC_OR_HERE (t);
+
+  for (i = 0; i < 3; i++)
+    {
+      args[i] = cxx_eval_constant_expression (call, TREE_OPERAND (t, i),
+					      allow_non_constant, addr,
+					      non_constant_p);
+      if (*non_constant_p)
+      	goto fail;
+    }
+
+  gcc_assert (TREE_CODE (TREE_TYPE (args[0])) == VECTOR_TYPE);
+  gcc_assert (TREE_CODE (TREE_TYPE (args[1])) == VECTOR_TYPE);
+  gcc_assert (TREE_CODE (TREE_TYPE (args[2])) == VECTOR_TYPE);
+
+  val = fold_ternary_loc (loc, VEC_PERM_EXPR, elttype, args[0], args[1], 
+			  args[2]);
+  if (val != NULL_TREE)
+    return val;
+
+ fail:
+  return t;
+}
+
 /* Attempt to reduce the expression T to a constant value.
    On failure, issue diagnostic and return error_mark_node.  */
 /* FIXME unify with c_fully_fold */
@@ -7770,6 +7807,11 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
 			     non_constant_p);
       break;
 
+    case VEC_PERM_EXPR:
+      r = cxx_eval_vec_perm_expr (call, t, allow_non_constant, addr,
+				  non_constant_p);
+      break;
+
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
     case NOP_EXPR:
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-16.inc b/gcc/testsuite/g++.dg/torture/vshuf-16.inc
new file mode 100644
index 0000000..7507305
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-16.inc
@@ -0,0 +1,50 @@
+/* Test fragment for vectors with 16 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }};
+
+
+
+
+
+constexpr VI mask1[] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, },
+			 { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87, 
+			   0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe, 0xff }	,
+			 { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
+			 { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 },
+			 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }};
+
+constexpr V out1[] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		       { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		       { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 },
+		       { 1, 3, 5, 7, 9, 11, 13, 15, 2, 4, 6, 8, 10, 12, 14, 16 },
+		       { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, 
+};
+
+constexpr V in2[] = { { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }};
+
+
+constexpr V in3 =  { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 };
+
+constexpr VI mask2[] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+			{ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 },
+			{ 7, 6, 5, 4, 16, 17, 18, 19, 31, 30, 29, 28, 3, 2, 1, 0 },
+			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+			{ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }};
+constexpr V out2[] = {   { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+			   { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 },
+			   { 17, 16, 15, 14, 30, 31, 32, 33, 45, 44, 43, 42, 13, 12, 11, 10 },
+			   { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 },
+			   { 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45 },
+};
+
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-2.inc b/gcc/testsuite/g++.dg/torture/vshuf-2.inc
new file mode 100644
index 0000000..6805583
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-2.inc
@@ -0,0 +1,22 @@
+/* Test fragment for vectors of 2 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { { A, B}, {A, B}, { A, B},
+	    	      { A, B}, {X, Y}, { X, Y}};
+constexpr VI mask1[] = { {0, 1}, {(unsigned)-16, 1}, {1, 0},
+	     	         {0, 0}, {  1, 1}, {1, 0}};
+constexpr V out1[] = { {A, B}, {A, B}, {B, A},
+	    	       {A, A}, {Y, Y}, {Y, X}};
+	    	  
+constexpr V in2[] = { { A, B}, {A, B}, {A, B}, {A, B},
+	    	      { A, B}, {A, B}, {A, B}};
+constexpr V in3 = {X, Y};
+constexpr VI mask2[] = { {0, 1}, {2, 3}, {0, 2}, {2, 1},
+	     	         {3, 0}, {0, 0}, {3, 3}};
+
+constexpr V out2[] = { {A, B}, {X, Y}, {A, X}, {X, B},
+	    	       {Y, A}, {A, A}, {Y, Y}};
+
+
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-4.inc b/gcc/testsuite/g++.dg/torture/vshuf-4.inc
new file mode 100644
index 0000000..2a18812
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-4.inc
@@ -0,0 +1,25 @@
+/* Test fragment for vectors of 4 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { {A, B, C, D}, {A, B, C, D}, {A, B, C, D}, {A, B, C, D},
+		     {A, B, C, D}, {W, X, Y, Z}, {W, X, Y, Z}, {W, X, Y, Z}};
+
+constexpr VI mask1[] = { {0, 1, 2, 3}, {0+1*4, 1+2*4, 2+3*4, 3+4*4}, {3, 2, 1, 0},
+			 {0, 3, 2, 1}, {0, 2, 1, 3}, {3, 1, 2, 0}, {0, 0, 0, 0},
+			 {1, 2, 1, 2}};
+
+constexpr V out1[] = { { A, B, C, D}, {A, B, C, D}, {D, C, B, A}, {A, D, C, B},
+		       { A, C, B, D}, {Z, X, Y, W}, {W, W, W, W}, {X, Y, X, Y}};
+
+
+constexpr V in2[] = { {A, B, C, D}, {A, B, C, D}, {A, B, C, D}, {A, B, C, D},
+		      {A, B, C, D}, {A, B, C, D}};
+constexpr V in3 = {W, X, Y, Z};
+constexpr VI mask2[] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {0, 4, 1, 5}, {0, 7, 4, 3},
+			 {0, 0, 0, 0}, {7, 7, 7, 7}};
+constexpr V out2[] = { {A, B, C, D}, {W, X, Y, Z}, {A, W, B, X}, {A, Z, W, D},
+		       {A, A, A, A}, {Z, Z, Z, Z}};
+
+
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-8.inc b/gcc/testsuite/g++.dg/torture/vshuf-8.inc
new file mode 100644
index 0000000..177e9f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-8.inc
@@ -0,0 +1,56 @@
+/* Test fragment for vectors of 8 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A2, B2, C2, D2, E2, F2, G2, H2 },
+		      { A2, B2, C2, D2, E2, F2, G2, H2 },
+		      { A2, B2, C2, D2, E2, F2, G2, H2 }};
+
+constexpr VI mask1[] = { {  0,  1,  2,  3,  4,  5,  6,  7 },
+		       { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87 },
+		       {  7,  6,  5,  4,  3,  2,  1,  0 },
+		       {  7,  0,  5,  3,  2,  4,  1,  6 },
+		       {  0,  2,  1,  3,  4,  6,  5,  7 },
+		       {  3,  1,  2,  0,  7,  5,  6,  4 },
+		       { 0, 0, 0, 0 },
+		       {  1,  6,  1,  6,  1,  6,  1,  6 }};
+
+constexpr V out1[] =   { { A1, B1, C1, D1, E1, F1, G1, H1 },
+			 { A1, B1, C1, D1, E1, F1, G1, H1 },
+			 { H1, G1, F1, E1, D1, C1, B1, A1 },
+			 { H1, A1, F1, D1, C1, E1, B1, G1 },
+			 { A1, C1, B1, D1, E1, G1, F1, H1 },
+			 { D2, B2, C2, A2, H2, F2, G2, E2 },
+			 { A2, A2, A2, A2, A2, A2, A2, A2 },
+			 { B2, G2, B2, G2, B2, G2, B2, G2 }};
+
+constexpr V in2 [] = {     { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 }};
+
+
+constexpr V in3 = { A2, B2, C2, D2, E2, F2, G2, H2};
+
+constexpr VI mask2[] = { { 0, 1, 2, 3, 4, 5, 6, 7 },
+		       {  8,  9, 10, 11, 12, 13, 14, 15 },
+		       {  0,  8,  1,  9,  2, 10,  3, 11 },
+		       {  0, 15,  4, 11, 12,  3,  7,  8 },
+		       {  0,  0,  0,  0,  0,  0,  0,  0 },
+		       { 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, 0x8e }};
+
+constexpr V out2[] = { { A1, B1, C1, D1, E1, F1, G1, H1 },
+		       { A2, B2, C2, D2, E2, F2, G2, H2 },
+		       { A1, A2, B1, B2, C1, C2, D1, D2 },
+		       { A1, H2, E1, D2, E2, D1, H1, A2 },
+		       { A1, A1, A1, A1, A1, A1, A1, A1 }, 
+		       { G2, G2, G2, G2, G2, G2, G2, G2 }};
+
+#endif
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-main.inc b/gcc/testsuite/g++.dg/torture/vshuf-main.inc
new file mode 100644
index 0000000..6c2310a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-main.inc
@@ -0,0 +1,29 @@
+/* Driver fragment for __builtin_shuffle of any vector shape.  */
+
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+extern "C" void abort(void);
+
+int main()
+{
+#ifndef UNSUPPORTED
+  int i;
+
+  for (i = 0; i < sizeof(in1)/sizeof(in1[0]); ++i)
+    {
+      V r = __builtin_shuffle(in1[i], mask1[i]);
+      if (__builtin_memcmp(&r, &out1[i], sizeof(V)) != 0)
+	abort();
+    }
+
+  for (i = 0; i < sizeof(in2)/sizeof(in2[0]); ++i)
+    {
+      V r = __builtin_shuffle(in2[i], in3, mask2[i]);
+      if (__builtin_memcmp(&r, &out2[i], sizeof(V)) != 0)
+	abort();
+    }
+#endif
+
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v16hi.C b/gcc/testsuite/g++.dg/torture/vshuf-v16hi.C
new file mode 100644
index 0000000..6277068
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v16hi.C
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned short V __attribute__((vector_size(32)));
+typedef V VI;
+
+#include "vshuf-16.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v16qi.C b/gcc/testsuite/g++.dg/torture/vshuf-v16qi.C
new file mode 100644
index 0000000..5680117
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v16qi.C
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned char V __attribute__((vector_size(16)));
+typedef V VI;
+
+#include "vshuf-16.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v2df.C b/gcc/testsuite/g++.dg/torture/vshuf-v2df.C
new file mode 100644
index 0000000..ba45078
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v2df.C
@@ -0,0 +1,17 @@
+// { dg-options "-std=c++11" }
+// // { dg-do run }
+#if __SIZEOF_DOUBLE__ == 8 && __SIZEOF_LONG_LONG__ == 8
+typedef double V __attribute__((vector_size(16)));
+typedef unsigned long long VI __attribute__((vector_size(16)));
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942
+#define B	2.7182818284590452354
+
+#define X	3.14159265358979323846
+#define Y	1.41421356237309504880
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v2di.C b/gcc/testsuite/g++.dg/torture/vshuf-v2di.C
new file mode 100644
index 0000000..a427284
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v2di.C
@@ -0,0 +1,18 @@
+// { dg-options "-std=c++11" }
+// // { dg-do run }
+
+#if __SIZEOF_LONG_LONG__ == 8
+typedef unsigned long long V __attribute__((vector_size(16)));
+typedef V VI;
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0x1112131415161718
+#define B	0x2122232425262728
+
+#define X	0xc1c2c3c4c5c6c7c8
+#define Y	0xd1d2d3d4d5d6d7d8
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v2sf.C b/gcc/testsuite/g++.dg/torture/vshuf-v2sf.C
new file mode 100644
index 0000000..dd229ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v2sf.C
@@ -0,0 +1,23 @@
+// { dg-options "-std=c++11" }
+// // { dg-do run }
+#if __SIZEOF_FLOAT__ == 4
+typedef float V __attribute__((vector_size(8)));
+# if __SIZEOF_INT__ == 4
+typedef unsigned int VI __attribute__((vector_size(8)));
+# elif __SIZEOF_LONG__ == 4
+typedef unsigned long VI __attribute__((vector_size(8)));
+# else
+#  define UNSUPPORTED
+# endif
+#else
+# define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942f
+#define B	2.7182818284590452354f
+
+#define X	3.14159265358979323846f
+#define Y	1.41421356237309504880f
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v2si.C b/gcc/testsuite/g++.dg/torture/vshuf-v2si.C
new file mode 100644
index 0000000..2670855
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v2si.C
@@ -0,0 +1,20 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+#if __SIZEOF_INT__ == 4
+typedef unsigned int V __attribute__((vector_size(8)));
+typedef V VI;
+#elif __SIZEOF_LONG__ == 4
+typedef unsigned long V __attribute__((vector_size(8)));
+typedef V VI;
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0x11121314
+#define B	0x21222324
+
+#define X	0xd1d2d3d4
+#define Y	0xe1e2e3e4
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v4df.C b/gcc/testsuite/g++.dg/torture/vshuf-v4df.C
new file mode 100644
index 0000000..e26f2c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v4df.C
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_DOUBLE__ == 8 && __SIZEOF_LONG_LONG__ == 8
+typedef double V __attribute__((vector_size(32)));
+typedef unsigned long long VI __attribute__((vector_size(32)));
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942
+#define B	2.7182818284590452354
+#define C	2.30258509299404568402
+#define D	1.4426950408889634074
+
+#define W	0.31830988618379067154
+#define X	3.14159265358979323846
+#define Y	1.41421356237309504880
+#define Z	0.70710678118654752440
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v4di.C b/gcc/testsuite/g++.dg/torture/vshuf-v4di.C
new file mode 100644
index 0000000..42cf60c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v4di.C
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_LONG_LONG__ == 8
+typedef unsigned long long V __attribute__((vector_size(32)));
+typedef V VI;
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0x1112131415161718
+#define B	0x2122232425262728
+#define C	0x3132333435363738
+#define D	0x4142434445464748
+
+#define W	0xc1c2c3c4c5c6c7c8
+#define X	0xd1d2d3d4d5d6d7d8
+#define Y	0xe1e2e3e4e5e6e7e8
+#define Z	0xf1f2f3f4f5f6f7f8
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v4sf.C b/gcc/testsuite/g++.dg/torture/vshuf-v4sf.C
new file mode 100644
index 0000000..c7d5843
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v4sf.C
@@ -0,0 +1,29 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+
+#if __SIZEOF_FLOAT__ == 4
+typedef float V __attribute__((vector_size(16)));
+# if __SIZEOF_INT__ == 4
+typedef unsigned int VI __attribute__((vector_size(16)));
+# elif __SIZEOF_LONG__ == 4
+typedef unsigned long VI __attribute__((vector_size(16)));
+# else
+#  define UNSUPPORTED
+# endif
+#else
+# define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942f
+#define B	2.7182818284590452354f
+#define C	2.30258509299404568402f
+#define D	1.4426950408889634074f
+
+#define W	0.31830988618379067154f
+#define X	3.14159265358979323846f
+#define Y	1.41421356237309504880f
+#define Z	0.70710678118654752440f
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v4si.C b/gcc/testsuite/g++.dg/torture/vshuf-v4si.C
new file mode 100644
index 0000000..af37de7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v4si.C
@@ -0,0 +1,25 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_INT__ == 4
+typedef unsigned int V __attribute__((vector_size(16)));
+typedef V VI;
+#elif __SIZEOF_LONG__ == 4
+typedef unsigned long V __attribute__((vector_size(16)));
+typedef V VI;
+#else
+# define UNSUPPORTED
+#endif
+
+#define A	0x11121314
+#define B	0x21222324
+#define C	0x31323334
+#define D	0x41424344
+
+#define W	0xc1c2c3c4
+#define X	0xd1d2d3d4
+#define Y	0xe1e2e3e4
+#define Z	0xf1f2f3f4
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v8hi.C b/gcc/testsuite/g++.dg/torture/vshuf-v8hi.C
new file mode 100644
index 0000000..33b20c68
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v8hi.C
@@ -0,0 +1,26 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned short V __attribute__((vector_size(16)));
+typedef V VI;
+
+#define A1	0x1112
+#define B1	0x2122
+#define C1	0x3132
+#define D1	0x4142
+#define E1	0x5152
+#define F1	0x6162
+#define G1	0x7172
+#define H1	0x8182
+
+#define A2	0x9192
+#define B2	0xa1a2
+#define C2	0xb1b2
+#define D2	0xc1c2
+#define E2	0xd1d2
+#define F2	0xe1e2
+#define G2	0xf1f2
+#define H2	0x0102
+
+#include "vshuf-8.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v8qi.C b/gcc/testsuite/g++.dg/torture/vshuf-v8qi.C
new file mode 100644
index 0000000..8681509
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v8qi.C
@@ -0,0 +1,26 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned char V __attribute__((vector_size(8)));
+typedef V VI;
+
+#define A1	0x11
+#define B1	0x12
+#define C1	0x13
+#define D1	0x14
+#define E1	0x15
+#define F1	0x16
+#define G1	0x17
+#define H1	0x18
+
+#define A2	0xf1
+#define B2	0xf2
+#define C2	0xf3
+#define D2	0xf4
+#define E2	0xf5
+#define F2	0xf6
+#define G2	0xf7
+#define H2	0xf8
+
+#include "vshuf-8.inc"
+#include "vshuf-main.inc"
diff --git a/gcc/testsuite/g++.dg/torture/vshuf-v8si.C b/gcc/testsuite/g++.dg/torture/vshuf-v8si.C
new file mode 100644
index 0000000..8583aa2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/vshuf-v8si.C
@@ -0,0 +1,33 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_INT__ == 4
+typedef unsigned int V __attribute__((vector_size(32)));
+typedef V VI;
+#elif __SIZEOF_LONG__ == 4
+typedef unsigned long V __attribute__((vector_size(32)));
+typedef V VI;
+#else
+# define UNSUPPORTED
+#endif
+
+#define A1	0x11121314
+#define B1	0x21222324
+#define C1	0x31323334
+#define D1	0x41424344
+#define E1	0x51525354
+#define F1	0x61626364
+#define G1	0x71727374
+#define H1	0x81828384
+
+#define A2	0x91929394
+#define B2	0xa1a2a3a4
+#define C2	0xb1b2b3b4
+#define D2	0xc1c2c3c4
+#define E2	0xd1d2d3d4
+#define F2	0xe1e2e3e4
+#define G2	0xf1f2f3f4
+#define H2	0x01020304
+
+#include "vshuf-8.inc"
+#include "vshuf-main.inc"

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
  2012-06-18 13:32 [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend Ramana Radhakrishnan
@ 2012-06-22  9:23 ` Ramana Radhakrishnan
  2012-06-25  5:56 ` Jason Merrill
  2012-07-28 14:44 ` Marc Glisse
  2 siblings, 0 replies; 7+ messages in thread
From: Ramana Radhakrishnan @ 2012-06-22  9:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: Patch Tracking, Jason Merrill, Marc Glisse

On 18 June 2012 14:04, Ramana Radhakrishnan
<ramana.radhakrishnan@linaro.org> wrote:
> Hi,
>
> This patch following on from the fix for turning on __builtin_shuffle
> for c++ , enables folding of vec_perm_exprs in the front-end for
> constexpr and constructor style values.  I was originally going to go
> with Marc's patch but then took a look at what it would take to
> support this properly which appeared to me to be just calling fold
> with the right parameters.
>
> With simple tests based on variations from c-c++-common/vshuf*.c using
> constexpr execution tests appear to pass - There is still an issue
> with the compiler giving an error on seeing a subscript operation with
> a __builtin_shuffle - I'm going to let that one for someone else to
> pick up because I don't have the time to pick this up right at this
> minute and the fact is that folks could use an extra vector for the
> time being.
>
> Regression tested with a bootstrap and testrun on powerpc /
> x86_64-linux-gnu and cross-tested on arm-linux-gnueabi
>
> Thoughts  ?

Ping .

Ramana

>
> regards,
> Ramana
>
> cp/
>
>        PR C++/51033
>        * semantics.c (constexpr_call): Fix typo in comment.
>        (cxx_eval_vec_perm_expr): New.
>        (cxx_eval_constant_expression): Fold VEC_PERM_EXPRs.
>
> testsuite/
>
>
>        * g++.dg/torture/vshuf-16.inc: New test.
>        * g++.dg/torture/vshuf-2.inc: New test.
>        * g++.dg/torture/vshuf-4.inc: New test.
>        * g++.dg/torture/vshuf-8.inc: New test.
>        * g++.dg/torture/vshuf-main.inc: New test.
>        * g++.dg/torture/vshuf-v16hi.C: New test.
>        * g++.dg/torture/vshuf-v16qi.C: New test.
>        * g++.dg/torture/vshuf-v2df.C: New test.
>        * g++.dg/torture/vshuf-v2di.C: New test.
>        * g++.dg/torture/vshuf-v2sf.C: New test.
>        * g++.dg/torture/vshuf-v2si.C: New test.
>        * g++.dg/torture/vshuf-v4df.C: New test.
>        * g++.dg/torture/vshuf-v4di.C: New test.
>        * g++.dg/torture/vshuf-v4sf.C: New test.
>        * g++.dg/torture/vshuf-v4si.C: New test.
>        * g++.dg/torture/vshuf-v8hi.C: New test.
>        * g++.dg/torture/vshuf-v8qi.C: New test.
>        * g++.dg/torture/vshuf-v8si.C: New test.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
  2012-06-18 13:32 [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend Ramana Radhakrishnan
  2012-06-22  9:23 ` Ramana Radhakrishnan
@ 2012-06-25  5:56 ` Jason Merrill
  2012-06-27 14:45   ` Ramana Radhakrishnan
  2012-07-28 14:44 ` Marc Glisse
  2 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2012-06-25  5:56 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches, Patch Tracking, Marc Glisse

On 06/18/2012 09:04 AM, Ramana Radhakrishnan wrote:
> +  location_t loc = EXPR_LOC_OR_HERE (t);

We should only use EXPR_LOC_OR_HERE for diagnostics.  For a location to 
use in building other expressions, use EXPR_LOCATION.

OK with that change.

Jason

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
  2012-06-25  5:56 ` Jason Merrill
@ 2012-06-27 14:45   ` Ramana Radhakrishnan
  0 siblings, 0 replies; 7+ messages in thread
From: Ramana Radhakrishnan @ 2012-06-27 14:45 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches, Patch Tracking, Marc Glisse

[-- Attachment #1: Type: text/plain, Size: 446 bytes --]

On 25 June 2012 04:32, Jason Merrill <jason@redhat.com> wrote:
> On 06/18/2012 09:04 AM, Ramana Radhakrishnan wrote:
>>
>> +  location_t loc = EXPR_LOC_OR_HERE (t);
>
>
> We should only use EXPR_LOC_OR_HERE for diagnostics.  For a location to use
> in building other expressions, use EXPR_LOCATION.

Thanks for the review. I've made that change and committed the following patch.

Ramana


>
> OK with that change.
>
> Jason
>

[-- Attachment #2: committed.patch --]
[-- Type: application/octet-stream, Size: 19943 bytes --]

Index: gcc/testsuite/g++.dg/torture/vshuf-16.inc
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-16.inc	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-16.inc	(revision 189017)
@@ -0,0 +1,50 @@
+/* Test fragment for vectors with 16 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }};
+
+
+
+
+
+constexpr VI mask1[] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, },
+			 { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87, 
+			   0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe, 0xff }	,
+			 { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
+			 { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 },
+			 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }};
+
+constexpr V out1[] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		       { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
+		       { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 },
+		       { 1, 3, 5, 7, 9, 11, 13, 15, 2, 4, 6, 8, 10, 12, 14, 16 },
+		       { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, 
+};
+
+constexpr V in2[] = { { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+		      { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }};
+
+
+constexpr V in3 =  { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 };
+
+constexpr VI mask2[] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+			{ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 },
+			{ 7, 6, 5, 4, 16, 17, 18, 19, 31, 30, 29, 28, 3, 2, 1, 0 },
+			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+			{ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }};
+constexpr V out2[] = {   { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 },
+			   { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 },
+			   { 17, 16, 15, 14, 30, 31, 32, 33, 45, 44, 43, 42, 13, 12, 11, 10 },
+			   { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 },
+			   { 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45 },
+};
+
+#endif
Index: gcc/testsuite/g++.dg/torture/vshuf-v8hi.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v8hi.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v8hi.C	(revision 189017)
@@ -0,0 +1,26 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned short V __attribute__((vector_size(16)));
+typedef V VI;
+
+#define A1	0x1112
+#define B1	0x2122
+#define C1	0x3132
+#define D1	0x4142
+#define E1	0x5152
+#define F1	0x6162
+#define G1	0x7172
+#define H1	0x8182
+
+#define A2	0x9192
+#define B2	0xa1a2
+#define C2	0xb1b2
+#define D2	0xc1c2
+#define E2	0xd1d2
+#define F2	0xe1e2
+#define G2	0xf1f2
+#define H2	0x0102
+
+#include "vshuf-8.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-2.inc
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-2.inc	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-2.inc	(revision 189017)
@@ -0,0 +1,22 @@
+/* Test fragment for vectors of 2 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { { A, B}, {A, B}, { A, B},
+	    	      { A, B}, {X, Y}, { X, Y}};
+constexpr VI mask1[] = { {0, 1}, {(unsigned)-16, 1}, {1, 0},
+	     	         {0, 0}, {  1, 1}, {1, 0}};
+constexpr V out1[] = { {A, B}, {A, B}, {B, A},
+	    	       {A, A}, {Y, Y}, {Y, X}};
+	    	  
+constexpr V in2[] = { { A, B}, {A, B}, {A, B}, {A, B},
+	    	      { A, B}, {A, B}, {A, B}};
+constexpr V in3 = {X, Y};
+constexpr VI mask2[] = { {0, 1}, {2, 3}, {0, 2}, {2, 1},
+	     	         {3, 0}, {0, 0}, {3, 3}};
+
+constexpr V out2[] = { {A, B}, {X, Y}, {A, X}, {X, B},
+	    	       {Y, A}, {A, A}, {Y, Y}};
+
+
+#endif
Index: gcc/testsuite/g++.dg/torture/vshuf-4.inc
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-4.inc	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-4.inc	(revision 189017)
@@ -0,0 +1,25 @@
+/* Test fragment for vectors of 4 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { {A, B, C, D}, {A, B, C, D}, {A, B, C, D}, {A, B, C, D},
+		     {A, B, C, D}, {W, X, Y, Z}, {W, X, Y, Z}, {W, X, Y, Z}};
+
+constexpr VI mask1[] = { {0, 1, 2, 3}, {0+1*4, 1+2*4, 2+3*4, 3+4*4}, {3, 2, 1, 0},
+			 {0, 3, 2, 1}, {0, 2, 1, 3}, {3, 1, 2, 0}, {0, 0, 0, 0},
+			 {1, 2, 1, 2}};
+
+constexpr V out1[] = { { A, B, C, D}, {A, B, C, D}, {D, C, B, A}, {A, D, C, B},
+		       { A, C, B, D}, {Z, X, Y, W}, {W, W, W, W}, {X, Y, X, Y}};
+
+
+constexpr V in2[] = { {A, B, C, D}, {A, B, C, D}, {A, B, C, D}, {A, B, C, D},
+		      {A, B, C, D}, {A, B, C, D}};
+constexpr V in3 = {W, X, Y, Z};
+constexpr VI mask2[] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {0, 4, 1, 5}, {0, 7, 4, 3},
+			 {0, 0, 0, 0}, {7, 7, 7, 7}};
+constexpr V out2[] = { {A, B, C, D}, {W, X, Y, Z}, {A, W, B, X}, {A, Z, W, D},
+		       {A, A, A, A}, {Z, Z, Z, Z}};
+
+
+#endif
Index: gcc/testsuite/g++.dg/torture/vshuf-8.inc
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-8.inc	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-8.inc	(revision 189017)
@@ -0,0 +1,56 @@
+/* Test fragment for vectors of 8 elements.  */
+
+#ifndef UNSUPPORTED
+
+constexpr V in1[] = { { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A1, B1, C1, D1, E1, F1, G1, H1 },
+		      { A2, B2, C2, D2, E2, F2, G2, H2 },
+		      { A2, B2, C2, D2, E2, F2, G2, H2 },
+		      { A2, B2, C2, D2, E2, F2, G2, H2 }};
+
+constexpr VI mask1[] = { {  0,  1,  2,  3,  4,  5,  6,  7 },
+		       { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87 },
+		       {  7,  6,  5,  4,  3,  2,  1,  0 },
+		       {  7,  0,  5,  3,  2,  4,  1,  6 },
+		       {  0,  2,  1,  3,  4,  6,  5,  7 },
+		       {  3,  1,  2,  0,  7,  5,  6,  4 },
+		       { 0, 0, 0, 0 },
+		       {  1,  6,  1,  6,  1,  6,  1,  6 }};
+
+constexpr V out1[] =   { { A1, B1, C1, D1, E1, F1, G1, H1 },
+			 { A1, B1, C1, D1, E1, F1, G1, H1 },
+			 { H1, G1, F1, E1, D1, C1, B1, A1 },
+			 { H1, A1, F1, D1, C1, E1, B1, G1 },
+			 { A1, C1, B1, D1, E1, G1, F1, H1 },
+			 { D2, B2, C2, A2, H2, F2, G2, E2 },
+			 { A2, A2, A2, A2, A2, A2, A2, A2 },
+			 { B2, G2, B2, G2, B2, G2, B2, G2 }};
+
+constexpr V in2 [] = {     { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 },
+			   { A1, B1, C1, D1, E1, F1, G1, H1 }};
+
+
+constexpr V in3 = { A2, B2, C2, D2, E2, F2, G2, H2};
+
+constexpr VI mask2[] = { { 0, 1, 2, 3, 4, 5, 6, 7 },
+		       {  8,  9, 10, 11, 12, 13, 14, 15 },
+		       {  0,  8,  1,  9,  2, 10,  3, 11 },
+		       {  0, 15,  4, 11, 12,  3,  7,  8 },
+		       {  0,  0,  0,  0,  0,  0,  0,  0 },
+		       { 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, 0x8e }};
+
+constexpr V out2[] = { { A1, B1, C1, D1, E1, F1, G1, H1 },
+		       { A2, B2, C2, D2, E2, F2, G2, H2 },
+		       { A1, A2, B1, B2, C1, C2, D1, D2 },
+		       { A1, H2, E1, D2, E2, D1, H1, A2 },
+		       { A1, A1, A1, A1, A1, A1, A1, A1 }, 
+		       { G2, G2, G2, G2, G2, G2, G2, G2 }};
+
+#endif
Index: gcc/testsuite/g++.dg/torture/vshuf-v16qi.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v16qi.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v16qi.C	(revision 189017)
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned char V __attribute__((vector_size(16)));
+typedef V VI;
+
+#include "vshuf-16.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v2si.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v2si.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v2si.C	(revision 189017)
@@ -0,0 +1,20 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+#if __SIZEOF_INT__ == 4
+typedef unsigned int V __attribute__((vector_size(8)));
+typedef V VI;
+#elif __SIZEOF_LONG__ == 4
+typedef unsigned long V __attribute__((vector_size(8)));
+typedef V VI;
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0x11121314
+#define B	0x21222324
+
+#define X	0xd1d2d3d4
+#define Y	0xe1e2e3e4
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v4si.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v4si.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v4si.C	(revision 189017)
@@ -0,0 +1,25 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_INT__ == 4
+typedef unsigned int V __attribute__((vector_size(16)));
+typedef V VI;
+#elif __SIZEOF_LONG__ == 4
+typedef unsigned long V __attribute__((vector_size(16)));
+typedef V VI;
+#else
+# define UNSUPPORTED
+#endif
+
+#define A	0x11121314
+#define B	0x21222324
+#define C	0x31323334
+#define D	0x41424344
+
+#define W	0xc1c2c3c4
+#define X	0xd1d2d3d4
+#define Y	0xe1e2e3e4
+#define Z	0xf1f2f3f4
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v8si.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v8si.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v8si.C	(revision 189017)
@@ -0,0 +1,33 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_INT__ == 4
+typedef unsigned int V __attribute__((vector_size(32)));
+typedef V VI;
+#elif __SIZEOF_LONG__ == 4
+typedef unsigned long V __attribute__((vector_size(32)));
+typedef V VI;
+#else
+# define UNSUPPORTED
+#endif
+
+#define A1	0x11121314
+#define B1	0x21222324
+#define C1	0x31323334
+#define D1	0x41424344
+#define E1	0x51525354
+#define F1	0x61626364
+#define G1	0x71727374
+#define H1	0x81828384
+
+#define A2	0x91929394
+#define B2	0xa1a2a3a4
+#define C2	0xb1b2b3b4
+#define D2	0xc1c2c3c4
+#define E2	0xd1d2d3d4
+#define F2	0xe1e2e3e4
+#define G2	0xf1f2f3f4
+#define H2	0x01020304
+
+#include "vshuf-8.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v2sf.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v2sf.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v2sf.C	(revision 189017)
@@ -0,0 +1,23 @@
+// { dg-options "-std=c++11" }
+// // { dg-do run }
+#if __SIZEOF_FLOAT__ == 4
+typedef float V __attribute__((vector_size(8)));
+# if __SIZEOF_INT__ == 4
+typedef unsigned int VI __attribute__((vector_size(8)));
+# elif __SIZEOF_LONG__ == 4
+typedef unsigned long VI __attribute__((vector_size(8)));
+# else
+#  define UNSUPPORTED
+# endif
+#else
+# define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942f
+#define B	2.7182818284590452354f
+
+#define X	3.14159265358979323846f
+#define Y	1.41421356237309504880f
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v4sf.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v4sf.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v4sf.C	(revision 189017)
@@ -0,0 +1,29 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+
+#if __SIZEOF_FLOAT__ == 4
+typedef float V __attribute__((vector_size(16)));
+# if __SIZEOF_INT__ == 4
+typedef unsigned int VI __attribute__((vector_size(16)));
+# elif __SIZEOF_LONG__ == 4
+typedef unsigned long VI __attribute__((vector_size(16)));
+# else
+#  define UNSUPPORTED
+# endif
+#else
+# define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942f
+#define B	2.7182818284590452354f
+#define C	2.30258509299404568402f
+#define D	1.4426950408889634074f
+
+#define W	0.31830988618379067154f
+#define X	3.14159265358979323846f
+#define Y	1.41421356237309504880f
+#define Z	0.70710678118654752440f
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v8qi.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v8qi.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v8qi.C	(revision 189017)
@@ -0,0 +1,26 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned char V __attribute__((vector_size(8)));
+typedef V VI;
+
+#define A1	0x11
+#define B1	0x12
+#define C1	0x13
+#define D1	0x14
+#define E1	0x15
+#define F1	0x16
+#define G1	0x17
+#define H1	0x18
+
+#define A2	0xf1
+#define B2	0xf2
+#define C2	0xf3
+#define D2	0xf4
+#define E2	0xf5
+#define F2	0xf6
+#define G2	0xf7
+#define H2	0xf8
+
+#include "vshuf-8.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v2di.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v2di.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v2di.C	(revision 189017)
@@ -0,0 +1,18 @@
+// { dg-options "-std=c++11" }
+// // { dg-do run }
+
+#if __SIZEOF_LONG_LONG__ == 8
+typedef unsigned long long V __attribute__((vector_size(16)));
+typedef V VI;
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0x1112131415161718
+#define B	0x2122232425262728
+
+#define X	0xc1c2c3c4c5c6c7c8
+#define Y	0xd1d2d3d4d5d6d7d8
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v4di.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v4di.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v4di.C	(revision 189017)
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_LONG_LONG__ == 8
+typedef unsigned long long V __attribute__((vector_size(32)));
+typedef V VI;
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0x1112131415161718
+#define B	0x2122232425262728
+#define C	0x3132333435363738
+#define D	0x4142434445464748
+
+#define W	0xc1c2c3c4c5c6c7c8
+#define X	0xd1d2d3d4d5d6d7d8
+#define Y	0xe1e2e3e4e5e6e7e8
+#define Z	0xf1f2f3f4f5f6f7f8
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-main.inc
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-main.inc	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-main.inc	(revision 189017)
@@ -0,0 +1,29 @@
+/* Driver fragment for __builtin_shuffle of any vector shape.  */
+
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+extern "C" void abort(void);
+
+int main()
+{
+#ifndef UNSUPPORTED
+  int i;
+
+  for (i = 0; i < sizeof(in1)/sizeof(in1[0]); ++i)
+    {
+      V r = __builtin_shuffle(in1[i], mask1[i]);
+      if (__builtin_memcmp(&r, &out1[i], sizeof(V)) != 0)
+	abort();
+    }
+
+  for (i = 0; i < sizeof(in2)/sizeof(in2[0]); ++i)
+    {
+      V r = __builtin_shuffle(in2[i], in3, mask2[i]);
+      if (__builtin_memcmp(&r, &out2[i], sizeof(V)) != 0)
+	abort();
+    }
+#endif
+
+  return 0;
+}
Index: gcc/testsuite/g++.dg/torture/vshuf-v16hi.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v16hi.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v16hi.C	(revision 189017)
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+typedef unsigned short V __attribute__((vector_size(32)));
+typedef V VI;
+
+#include "vshuf-16.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v2df.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v2df.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v2df.C	(revision 189017)
@@ -0,0 +1,17 @@
+// { dg-options "-std=c++11" }
+// // { dg-do run }
+#if __SIZEOF_DOUBLE__ == 8 && __SIZEOF_LONG_LONG__ == 8
+typedef double V __attribute__((vector_size(16)));
+typedef unsigned long long VI __attribute__((vector_size(16)));
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942
+#define B	2.7182818284590452354
+
+#define X	3.14159265358979323846
+#define Y	1.41421356237309504880
+
+#include "vshuf-2.inc"
+#include "vshuf-main.inc"
Index: gcc/testsuite/g++.dg/torture/vshuf-v4df.C
===================================================================
--- gcc/testsuite/g++.dg/torture/vshuf-v4df.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/vshuf-v4df.C	(revision 189017)
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+#if __SIZEOF_DOUBLE__ == 8 && __SIZEOF_LONG_LONG__ == 8
+typedef double V __attribute__((vector_size(32)));
+typedef unsigned long long VI __attribute__((vector_size(32)));
+#else
+#define UNSUPPORTED
+#endif
+
+#define A	0.69314718055994530942
+#define B	2.7182818284590452354
+#define C	2.30258509299404568402
+#define D	1.4426950408889634074
+
+#define W	0.31830988618379067154
+#define X	3.14159265358979323846
+#define Y	1.41421356237309504880
+#define Z	0.70710678118654752440
+
+#include "vshuf-4.inc"
+#include "vshuf-main.inc"
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 189016)
+++ gcc/cp/semantics.c	(working copy)
@@ -6209,7 +6209,7 @@
 typedef struct GTY(()) constexpr_call {
   /* Description of the constexpr function definition.  */
   constexpr_fundef *fundef;
-  /* Parameter bindings enironment.  A TREE_LIST where each TREE_PURPOSE
+  /* Parameter bindings environment.  A TREE_LIST where each TREE_PURPOSE
      is a parameter _DECL and the TREE_VALUE is the value of the parameter.
      Note: This arrangement is made to accomodate the use of
      iterative_hash_template_arg (see pt.c).  If you change this
@@ -6233,7 +6233,10 @@
 
 static tree cxx_eval_constant_expression (const constexpr_call *, tree,
 					  bool, bool, bool *);
+static tree cxx_eval_vec_perm_expr (const constexpr_call *, tree, bool, bool,
+				    bool *);
 
+
 /* Compute a hash value for a constexpr call representation.  */
 
 static hashval_t
@@ -7495,6 +7498,39 @@
     }
 }
 
+/* Evaluate VEC_PERM_EXPR (v1, v2, mask).  */
+static tree
+cxx_eval_vec_perm_expr (const constexpr_call *call, tree t, 
+			bool allow_non_constant, bool addr,
+			bool * non_constant_p)
+{
+  int i;
+  tree args[3];
+  tree val;
+  tree elttype = TREE_TYPE (t);
+
+  for (i = 0; i < 3; i++)
+    {
+      args[i] = cxx_eval_constant_expression (call, TREE_OPERAND (t, i),
+					      allow_non_constant, addr,
+					      non_constant_p);
+      if (*non_constant_p)
+      	goto fail;
+    }
+
+  gcc_assert (TREE_CODE (TREE_TYPE (args[0])) == VECTOR_TYPE);
+  gcc_assert (TREE_CODE (TREE_TYPE (args[1])) == VECTOR_TYPE);
+  gcc_assert (TREE_CODE (TREE_TYPE (args[2])) == VECTOR_TYPE);
+
+  val = fold_ternary_loc (EXPR_LOCATION (t), VEC_PERM_EXPR, elttype, 
+			  args[0], args[1], args[2]);
+  if (val != NULL_TREE)
+    return val;
+
+ fail:
+  return t;
+}
+
 /* Attempt to reduce the expression T to a constant value.
    On failure, issue diagnostic and return error_mark_node.  */
 /* FIXME unify with c_fully_fold */
@@ -7773,6 +7809,11 @@
 			     non_constant_p);
       break;
 
+    case VEC_PERM_EXPR:
+      r = cxx_eval_vec_perm_expr (call, t, allow_non_constant, addr,
+				  non_constant_p);
+      break;
+
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
     case NOP_EXPR:

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
  2012-06-18 13:32 [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend Ramana Radhakrishnan
  2012-06-22  9:23 ` Ramana Radhakrishnan
  2012-06-25  5:56 ` Jason Merrill
@ 2012-07-28 14:44 ` Marc Glisse
  2012-07-30 11:41   ` Ramana Radhakrishnan
  2012-08-03 22:08   ` Marc Glisse
  2 siblings, 2 replies; 7+ messages in thread
From: Marc Glisse @ 2012-07-28 14:44 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches, Patch Tracking, Jason Merrill

On Mon, 18 Jun 2012, Ramana Radhakrishnan wrote:

> This patch following on from the fix for turning on __builtin_shuffle
> for c++ , enables folding of vec_perm_exprs in the front-end for
> constexpr and constructor style values.

Hello,

I took a look, and the example I gave in
http://gcc.gnu.org/ml/gcc-patches/2012-06/msg01066.html
although it doesn't crash the compiler anymore, still fails to compile. I 
am not sure: were you just trying to remove the ICE, or actually support 
this use?

#include <x86intrin.h>
int main(){
   constexpr __m128d x={1.,2.};
   constexpr __m128i y={1,0};
   constexpr __m128d z=__builtin_shuffle(x,y);
}

$ g++ -std=gnu++11 m.cc
m.cc: In function 'int main()':
m.cc:5:23: error: '#'vec_perm_expr' not supported by dump_expr#<expression 
error>' is not a constant expression
    constexpr __m128d z=__builtin_shuffle(x,y);
                        ^

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
  2012-07-28 14:44 ` Marc Glisse
@ 2012-07-30 11:41   ` Ramana Radhakrishnan
  2012-08-03 22:08   ` Marc Glisse
  1 sibling, 0 replies; 7+ messages in thread
From: Ramana Radhakrishnan @ 2012-07-30 11:41 UTC (permalink / raw)
  To: Marc Glisse; +Cc: gcc-patches, Patch Tracking, Jason Merrill

On 28 July 2012 10:26, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Mon, 18 Jun 2012, Ramana Radhakrishnan wrote:
>
>> This patch following on from the fix for turning on __builtin_shuffle
>> for c++ , enables folding of vec_perm_exprs in the front-end for
>> constexpr and constructor style values.
>
>
> Hello,
>
> I took a look, and the example I gave in
> http://gcc.gnu.org/ml/gcc-patches/2012-06/msg01066.html
> although it doesn't crash the compiler anymore, still fails to compile. I am
> not sure: were you just trying to remove the ICE, or actually support this
> use?

The intent was to actually support this use properly. I'll have a look
but it's unlikely to be today.


Ramana

>
> #include <x86intrin.h>
> int main(){
>   constexpr __m128d x={1.,2.};
>   constexpr __m128i y={1,0};
>   constexpr __m128d z=__builtin_shuffle(x,y);
> }
>
> $ g++ -std=gnu++11 m.cc
> m.cc: In function 'int main()':
> m.cc:5:23: error: '#'vec_perm_expr' not supported by dump_expr#<expression
> error>' is not a constant expression
>    constexpr __m128d z=__builtin_shuffle(x,y);
>                        ^
>
> --
> Marc Glisse

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend.
  2012-07-28 14:44 ` Marc Glisse
  2012-07-30 11:41   ` Ramana Radhakrishnan
@ 2012-08-03 22:08   ` Marc Glisse
  1 sibling, 0 replies; 7+ messages in thread
From: Marc Glisse @ 2012-08-03 22:08 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: gcc-patches, Patch Tracking, Jason Merrill

On Sat, 28 Jul 2012, Marc Glisse wrote:

> On Mon, 18 Jun 2012, Ramana Radhakrishnan wrote:
>
>> This patch following on from the fix for turning on __builtin_shuffle
>> for c++ , enables folding of vec_perm_exprs in the front-end for
>> constexpr and constructor style values.
>
> Hello,
>
> I took a look, and the example I gave in
> http://gcc.gnu.org/ml/gcc-patches/2012-06/msg01066.html
> although it doesn't crash the compiler anymore, still fails to compile. I am 
> not sure: were you just trying to remove the ICE, or actually support this 
> use?
>
> #include <x86intrin.h>
> int main(){
>  constexpr __m128d x={1.,2.};
>  constexpr __m128i y={1,0};
>  constexpr __m128d z=__builtin_shuffle(x,y);
> }
>
> $ g++ -std=gnu++11 m.cc
> m.cc: In function 'int main()':
> m.cc:5:23: error: '#'vec_perm_expr' not supported by dump_expr#<expression 
> error>' is not a constant expression
>   constexpr __m128d z=__builtin_shuffle(x,y);
>                       ^

The issue seems to be that we call fold_ternary_loc with a last argument 
that is a CONSTRUCTOR whereas the VEC_PERM_EXPR case expects a VECTOR_CST.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-08-03 22:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-18 13:32 [RFC C++ / PR51033 ] Handle __builtin_shuffle in constexpr properly in the C++ frontend Ramana Radhakrishnan
2012-06-22  9:23 ` Ramana Radhakrishnan
2012-06-25  5:56 ` Jason Merrill
2012-06-27 14:45   ` Ramana Radhakrishnan
2012-07-28 14:44 ` Marc Glisse
2012-07-30 11:41   ` Ramana Radhakrishnan
2012-08-03 22:08   ` Marc Glisse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).