re PR c++/54427 (Expose more vector extensions)
authorMarc Glisse <marc.glisse@inria.fr>
Thu, 25 Oct 2012 13:02:42 +0000 (15:02 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Thu, 25 Oct 2012 13:02:42 +0000 (13:02 +0000)
2012-10-25  Marc Glisse  <marc.glisse@inria.fr>

PR c++/54427

gcc/
* tree.c (signed_or_unsigned_type_for): Handle vectors.

gcc/cp/
* typeck.c (build_x_conditional_expr): Handle VEC_COND_EXPR.
* call.c (build_conditional_expr_1): Likewise.

gcc/c-family/
* c-common.c (scalar_to_vector): Handle VEC_COND_EXPR.

gcc/testsuite/
* g++.dg/ext/vector19.C: New testcase.

From-SVN: r192808

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vector19.C [new file with mode: 0644]
gcc/tree.c

index 0b8655292a86c789f9edb7e90ac1cc0496f3221b..542856abe2f8e4e394ace9607f6c3cb9032dc321 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-25  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       * tree.c (signed_or_unsigned_type_for): Handle vectors.
+
 2012-10-25  Jan Hubicka  <jh@suse.cz>
 
        * ipa-inline.c (recursive_inlining): Redirect to master
index cf43137f4442c797f571a571d671c83f5f83eba4..82f1fa22083adee3d91906dcb75e0fcda3b2c17d 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-25  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       * c-common.c (scalar_to_vector): Handle VEC_COND_EXPR.
+
 2012-10-23  Joseph Myers  <joseph@codesourcery.com>
 
        * c-common.h (pch_cpp_save_state): Declare.
index 34cfb98f85ba53e994e1a551649494caddf2fdb5..840bc84c6d245192beef97312065add4f4710981 100644 (file)
@@ -11474,6 +11474,8 @@ scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1,
        integer_only_op = true;
        /* ... fall through ...  */
 
+      case VEC_COND_EXPR:
+
       case PLUS_EXPR:
       case MINUS_EXPR:
       case MULT_EXPR:
index 9d5dde7ba92da2f134dd59fb91684e69a01d3cf1..c7c67e29bbf78af5fec7bbcaf1068b77b38c1f30 100644 (file)
@@ -1,3 +1,9 @@
+2012-10-25  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       * typeck.c (build_x_conditional_expr): Handle VEC_COND_EXPR.
+       * call.c (build_conditional_expr_1): Likewise.
+
 2012-10-25  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/34892
index e21049b8e648a803d8421244835206a7d85eaf3e..df241056d2ed0d2f5e7593d88f59aa1dec9bb50d 100644 (file)
@@ -4373,18 +4373,90 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
        arg2 = arg1 = save_expr (arg1);
     }
 
+  /* If something has already gone wrong, just pass that fact up the
+     tree.  */
+  if (error_operand_p (arg1)
+      || error_operand_p (arg2)
+      || error_operand_p (arg3))
+    return error_mark_node;
+
+  orig_arg2 = arg2;
+  orig_arg3 = arg3;
+
+  if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1)))
+    {
+      arg1 = force_rvalue (arg1, complain);
+      arg2 = force_rvalue (arg2, complain);
+      arg3 = force_rvalue (arg3, complain);
+
+      tree arg1_type = TREE_TYPE (arg1);
+      arg2_type = TREE_TYPE (arg2);
+      arg3_type = TREE_TYPE (arg3);
+
+      if (TREE_CODE (arg2_type) != VECTOR_TYPE
+         && TREE_CODE (arg3_type) != VECTOR_TYPE)
+       {
+         if (complain & tf_error)
+           error ("at least one operand of a vector conditional operator "
+                  "must be a vector");
+         return error_mark_node;
+       }
+
+      if ((TREE_CODE (arg2_type) == VECTOR_TYPE)
+         != (TREE_CODE (arg3_type) == VECTOR_TYPE))
+       {
+         enum stv_conv convert_flag =
+           scalar_to_vector (input_location, VEC_COND_EXPR, arg2, arg3,
+                             complain & tf_error);
+
+         switch (convert_flag)
+           {
+             case stv_error:
+               return error_mark_node;
+             case stv_firstarg:
+               {
+                 arg2 = convert (TREE_TYPE (arg3_type), arg2);
+                 arg2 = build_vector_from_val (arg3_type, arg2);
+                 arg2_type = TREE_TYPE (arg2);
+                 break;
+               }
+             case stv_secondarg:
+               {
+                 arg3 = convert (TREE_TYPE (arg2_type), arg3);
+                 arg3 = build_vector_from_val (arg2_type, arg3);
+                 arg3_type = TREE_TYPE (arg3);
+                 break;
+               }
+             default:
+               break;
+           }
+       }
+
+      if (!same_type_p (arg2_type, arg3_type)
+         || TYPE_VECTOR_SUBPARTS (arg1_type)
+            != TYPE_VECTOR_SUBPARTS (arg2_type)
+         || TYPE_SIZE (arg1_type) != TYPE_SIZE (arg2_type))
+       {
+         if (complain & tf_error)
+           error ("incompatible vector types in conditional expression: "
+                  "%qT, %qT and %qT", TREE_TYPE (arg1), TREE_TYPE (orig_arg2),
+                  TREE_TYPE (orig_arg3));
+         return error_mark_node;
+       }
+
+      if (!COMPARISON_CLASS_P (arg1))
+       arg1 = build2 (NE_EXPR, signed_type_for (arg1_type), arg1,
+                      build_zero_cst (arg1_type));
+      return build3 (VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
+    }
+
   /* [expr.cond]
 
      The first expression is implicitly converted to bool (clause
      _conv_).  */
   arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
                                            LOOKUP_NORMAL);
-
-  /* If something has already gone wrong, just pass that fact up the
-     tree.  */
-  if (error_operand_p (arg1)
-      || error_operand_p (arg2)
-      || error_operand_p (arg3))
+  if (error_operand_p (arg1))
     return error_mark_node;
 
   /* [expr.cond]
@@ -4394,8 +4466,6 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
      array-to-pointer (_conv.array_), and function-to-pointer
      (_conv.func_) standard conversions are performed on the second
      and third operands.  */
-  orig_arg2 = arg2;
-  orig_arg3 = arg3;
   arg2_type = unlowered_expr_type (arg2);
   arg3_type = unlowered_expr_type (arg3);
   if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
index eaa0935dc98674865aaf1adbb84cea15d221aee2..2514b6fc74144c52aab67b9af10356975427e4c1 100644 (file)
@@ -5810,7 +5810,8 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
     }
 
   expr = build_conditional_expr (ifexp, op1, op2, complain);
-  if (processing_template_decl && expr != error_mark_node)
+  if (processing_template_decl && expr != error_mark_node
+      && TREE_CODE (expr) != VEC_COND_EXPR)
     {
       tree min = build_min_non_dep (COND_EXPR, expr,
                                    orig_ifexp, orig_op1, orig_op2);
index 6c0a2f73921cdf9bff4f665addcee6f56ac068da..30fced628560b541596de1bde0bb52f7b62788be 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-25  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR c++/54427
+       * g++.dg/ext/vector19.C: New testcase.
+
 2012-10-25  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/54902
diff --git a/gcc/testsuite/g++.dg/ext/vector19.C b/gcc/testsuite/g++.dg/ext/vector19.C
new file mode 100644 (file)
index 0000000..ec08e7c
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=c++11 -mavx2" } */
+
+// The target restrictions and the -mavx2 flag are meant to disappear
+// once vector lowering is in place.
+
+typedef double vec __attribute__((vector_size(2*sizeof(double))));
+typedef signed char vec2 __attribute__((vector_size(16)));
+typedef unsigned char vec2u __attribute__((vector_size(16)));
+
+void f (vec *x, vec *y, vec *z)
+{
+  *x = (*y < *z) ? *x : *y;
+}
+
+void g (vec *x, vec *y, vec *z)
+{
+  *x = (*y < *z) ? *x : 42;
+}
+
+void h (vec *x, vec *y, vec *z)
+{
+  *x = (*y < *z) ? 3. : *y;
+}
+
+void i1 (vec *x, vec *y, vec *z)
+{
+  auto c = *y < *z;
+  *x = c ? *x : *y;
+}
+
+void i2 (vec2 *x, vec2 *y, vec2u *z)
+{
+  *x = *y ? *x : *y;
+  *y = *z ? *x : *y;
+}
+
+void j (vec2 *x, vec2 *y, vec2 *z, vec *t)
+{
+  *x = (*y < *z) ? *x : 4.2; /* { dg-error "" } */
+  *y = (*x < *z) ? 2.5 : *y; /* { dg-error "" } */
+  *t = *t ? *t : *t; /* { dg-error "" } */
+  *z = (*x < *z) ? '1' : '0'; /* { dg-error "" } */
+  // The last one may eventually be accepted.
+}
+
+template <class A, class B>
+auto k (A *a, B b) -> decltype (*a ? *a : b);
+
+void k (...) {}
+
+void l (vec2 *v, double x)
+{
+  k (v, x);
+}
+
index 7cb1ea14d1d7652f16e0f9dc8a21cb625639a545..c3642e3cc3573a0c192e858794929efa3ce489e1 100644 (file)
@@ -10241,6 +10241,17 @@ signed_or_unsigned_type_for (int unsignedp, tree type)
   if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp)
     return type;
 
+  if (TREE_CODE (type) == VECTOR_TYPE)
+    {
+      tree inner = TREE_TYPE (type);
+      tree inner2 = signed_or_unsigned_type_for (unsignedp, inner);
+      if (!inner2)
+       return NULL_TREE;
+      if (inner == inner2)
+       return type;
+      return build_vector_type (inner2, TYPE_VECTOR_SUBPARTS (type));
+    }
+
   if (!INTEGRAL_TYPE_P (type)
       && !POINTER_TYPE_P (type))
     return NULL_TREE;