re PR c++/54427 (Expose more vector extensions)
authorMarc Glisse <marc.glisse@inria.fr>
Fri, 3 Oct 2014 19:57:01 +0000 (21:57 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Fri, 3 Oct 2014 19:57:01 +0000 (19:57 +0000)
2014-10-03  Marc Glisse  <marc.glisse@inria.fr>

PR c++/54427
PR c++/57198
PR c++/58845
gcc/c-family/
* c-common.c (warn_logical_operator): Punt for vectors.
gcc/cp/
* typeck.c (cp_build_binary_op): save_expr after convert to save
redundant operations.
[TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR]: Handle vectors.
(cp_build_unary_op) [TRUTH_NOT_EXPR]: Likewise.
gcc/
* doc/extend.texi (Vector Extensions): Document &&, ||, ! in C++.
gcc/testsuite/
* g++.dg/ext/vector9.C: Update, not an error anymore.
* g++.dg/ext/vector27.C: Replace with new test.
* g++.dg/ext/vector28.C: New file.
* g++.dg/other/error23.C: Update to a different error.

From-SVN: r215872

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vector27.C
gcc/testsuite/g++.dg/ext/vector28.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/vector9.C
gcc/testsuite/g++.dg/other/error23.C

index 4bf61ab521241bd6c2d79bba57927b3f6b0e05dc..8c96f5225a2fcee9521aeb8e031e50f53ec58b2a 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       PR c++/57198
+       PR c++/58845
+       * doc/extend.texi (Vector Extensions): Document &&, ||, ! in C++.
+
 2014-10-03  Jan Hubicka  <hubicka@ucw.cz>
 
        * cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
index fef201b799bc15d86e29c5f7b4418da8983121ba..8f448878edc7f298e55113ac00804d5a2daada1d 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       PR c++/57198
+       PR c++/58845
+       * c-common.c (warn_logical_operator): Punt for vectors.
+
 2014-10-01  Edward Smith-Rowland  <3dw4rd@verizon.net>
 
        Implement SD-6: SG10 Feature Test Recommendations
index b16d030ae2bcba16ee4ab0d814727035a6f7a0d6..e69d128a2cdc14b0452702e7ca4413bf2ca47b71 100644 (file)
@@ -1677,6 +1677,10 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
           || INTEGRAL_TYPE_P (TREE_TYPE (op_right))))
     return;
 
+  /* The range computations only work with scalars.  */
+  if (VECTOR_TYPE_P (TREE_TYPE (op_left))
+      || VECTOR_TYPE_P (TREE_TYPE (op_right)))
+    return;
 
   /* We first test whether either side separately is trivially true
      (with OR) or trivially false (with AND).  If so, do not warn.
index 7a703aae203738db3ef4cafcfcdb95fd5678191b..c0b6fb5d1f9fd58ded9e47a5c48d9fec1167fc2a 100644 (file)
@@ -1,3 +1,13 @@
+2014-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       PR c++/57198
+       PR c++/58845
+       * typeck.c (cp_build_binary_op): save_expr after convert to save
+       redundant operations.
+       [TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR]: Handle vectors.
+       (cp_build_unary_op) [TRUTH_NOT_EXPR]: Likewise.
+
 2014-10-03  Jason Merrill  <jason@redhat.com>
 
        * decl.c (start_decl): Complain about static/thread_local vars
index 61d52bdb8332a6c70a9110f3f98c5c17e7d2af23..6a357bfca99ed0d96637a3cd6339d4f95a5f2622 100644 (file)
@@ -4045,8 +4045,8 @@ cp_build_binary_op (location_t location,
             return error_mark_node;
           case stv_firstarg:
             {
-             op0 = save_expr (op0);
               op0 = convert (TREE_TYPE (type1), op0);
+             op0 = save_expr (op0);
               op0 = build_vector_from_val (type1, op0);
               type0 = TREE_TYPE (op0);
               code0 = TREE_CODE (type0);
@@ -4055,8 +4055,8 @@ cp_build_binary_op (location_t location,
             }
           case stv_secondarg:
             {
-             op1 = save_expr (op1);
               op1 = convert (TREE_TYPE (type0), op1);
+             op1 = save_expr (op1);
               op1 = build_vector_from_val (type0, op1);
               type1 = TREE_TYPE (op1);
               code1 = TREE_CODE (type1);
@@ -4191,11 +4191,49 @@ cp_build_binary_op (location_t location,
     case TRUTH_ORIF_EXPR:
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
-      if (VECTOR_TYPE_P (type0) || VECTOR_TYPE_P (type1))
+      if (!VECTOR_TYPE_P (type0) && VECTOR_TYPE_P (type1))
        {
-         sorry ("logical operation on vector type");
-         return error_mark_node;
+         if (!COMPARISON_CLASS_P (op1))
+           op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
+                                     build_zero_cst (type1), complain);
+         if (code == TRUTH_ANDIF_EXPR)
+           {
+             tree z = build_zero_cst (TREE_TYPE (op1));
+             return build_conditional_expr (location, op0, op1, z, complain);
+           }
+         else if (code == TRUTH_ORIF_EXPR)
+           {
+             tree m1 = build_all_ones_cst (TREE_TYPE (op1));
+             return build_conditional_expr (location, op0, m1, op1, complain);
+           }
+         else
+           gcc_unreachable ();
        }
+      if (VECTOR_TYPE_P (type0))
+       {
+         if (!COMPARISON_CLASS_P (op0))
+           op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
+                                     build_zero_cst (type0), complain);
+         if (!VECTOR_TYPE_P (type1))
+           {
+             tree m1 = build_all_ones_cst (TREE_TYPE (op0));
+             tree z = build_zero_cst (TREE_TYPE (op0));
+             op1 = build_conditional_expr (location, op1, z, m1, complain);
+           }
+         else if (!COMPARISON_CLASS_P (op1))
+           op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
+                                     build_zero_cst (type1), complain);
+
+         if (code == TRUTH_ANDIF_EXPR)
+           code = BIT_AND_EXPR;
+         else if (code == TRUTH_ORIF_EXPR)
+           code = BIT_IOR_EXPR;
+         else
+           gcc_unreachable ();
+
+         return cp_build_binary_op (location, code, op0, op1, complain);
+       }
+
       result_type = boolean_type_node;
       break;
 
@@ -5685,6 +5723,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
       break;
 
     case TRUTH_NOT_EXPR:
+      if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg)))
+       return cp_build_binary_op (input_location, EQ_EXPR, arg,
+                                  build_zero_cst (TREE_TYPE (arg)), complain);
       arg = perform_implicit_conversion (boolean_type_node, arg,
                                         complain);
       val = invert_truthvalue_loc (input_location, arg);
index c78ffb2dabc184e7fa320f8b66bc3dce68832007..de056618226908b4dada17806ae4fd0184066f1f 100644 (file)
@@ -7918,6 +7918,13 @@ vector. If both @code{b} and @code{c} are scalars and the type of
 @code{b} and @code{c} are converted to a vector type whose elements have
 this type and with the same number of elements as @code{a}.
 
+In C++, the logic operators @code{!, &&, ||} are available for vectors.
+@code{!v} is equivalent to @code{v == 0}, @code{a && b} is equivalent to
+@code{a!=0 & b!=0} and @code{a || b} is equivalent to @code{a!=0 | b!=0}.
+For mixed operations between a scalar @code{s} and a vector @code{v},
+@code{s && v} is equivalent to @code{s?v!=0:0} (the evaluation is
+short-circuit) and @code{v && s} is equivalent to @code{v!=0 & (s?-1:0)}.
+
 Vector shuffling is available using functions
 @code{__builtin_shuffle (vec, mask)} and
 @code{__builtin_shuffle (vec0, vec1, mask)}.
index 2753273bd81203e7521f18f9e35991e96823146b..4c4c6049018f32782e99e13bf6d1227f4e71bed5 100644 (file)
@@ -1,3 +1,13 @@
+2014-10-03  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       PR c++/57198
+       PR c++/58845
+       * g++.dg/ext/vector9.C: Update, not an error anymore.
+       * g++.dg/ext/vector27.C: Replace with new test.
+       * g++.dg/ext/vector28.C: New file.
+       * g++.dg/other/error23.C: Update to a different error.
+
 2014-10-03  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.dg/torture/vshuf-v8df.c: New test.
index 288e13c558d4711f638aeeb57fe981e609bb7405..2f29577a4f0ab66ae482d386725ec87779d752fe 100644 (file)
@@ -1,7 +1,13 @@
-// PR c++/58845
+/* { dg-do compile } */
 
-void foo()
+typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
+typedef float vecf __attribute__ ((vector_size (4 * sizeof (float))));
+
+void f (veci *a, veci *b, int c)
+{
+  *a = !*a || *b < ++c;
+}
+void g (vecf *a, vecf *b)
 {
-  int v __attribute__((vector_size(8)));
-  v = v || v;                  // { dg-bogus "" "" { xfail *-*-* } }
+  *a = (*a < 1 && !(*b > 2)) ? *a + *b : 3;
 }
diff --git a/gcc/testsuite/g++.dg/ext/vector28.C b/gcc/testsuite/g++.dg/ext/vector28.C
new file mode 100644 (file)
index 0000000..ea48c96
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
+typedef float vecf __attribute__ ((vector_size (4 * sizeof (float))));
+
+void f (veci *a, vecf *b, int c)
+{
+  *a = c || *b;
+  *a = *a || c;
+}
index 52b3f1714444ad9373ea871269468c4b9c1d7726..42d150dd345c015207e8ea22293c6c29db550e81 100644 (file)
@@ -6,5 +6,5 @@ typedef int   v4i __attribute__((vector_size(8)));
 void foo()
 {
   v4f v;
-  !(v4i)v; // { dg-error "v4i|argument" }
+  !(v4i)v;
 }
index 959fe4075e6f8ebb500770db26e6400fb2c28def..c60603e8ff5fdaca8d36f31f97c8c4930322d30f 100644 (file)
@@ -2,4 +2,4 @@
 // { dg-do compile }
 
 int v __attribute ((vector_size (8)));
-bool b = !(v - v);     // { dg-error "could not convert .\\(__vector.2. int\\)\\{0, 0\\}. from .__vector.2. int. to .bool.|in argument to unary" }
+bool b = !(v - v);     // { dg-error "not convert .__vector.2. int. to .bool. in initialization" }