re PR c++/10611 (operations on vector mode not recognized in C++)
authorAldy Hernandez <aldyh@redhat.com>
Fri, 10 Jun 2005 17:35:37 +0000 (17:35 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Fri, 10 Jun 2005 17:35:37 +0000 (17:35 +0000)
        PR c++/10611
        * cvt.c (build_expr_type_conversion): Same.
        * typeck.c (build_binary_op): Handle vectors.
        (common_type): Same.
        (type_after_usual_arithmetic_conversions): Same.
        * testsuite/g++.dg/conversion/simd2.C: New.

From-SVN: r100823

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/conversion/simd2.C [new file with mode: 0644]

index f08a2c65803f0b2a66d4bb30fe16e16119fec8af..82b0ee281fd2ee1e2dadc63701cc712aed9bea2b 100644 (file)
@@ -1,3 +1,12 @@
+2005-06-10  Aldy Hernandez  <aldyh@redhat.com>
+
+       PR c++/10611
+       * cvt.c (build_expr_type_conversion): Same.
+       * typeck.c (build_binary_op): Handle vectors.
+       (common_type): Same.
+       (type_after_usual_arithmetic_conversions): Same.
+       * testsuite/g++.dg/conversion/simd2.C: New.
+
 2005-06-08  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/19497
index 5150fcf55487c8e17cfa7ef6b0622b4d71e4d989..c7ffb166f8135c9b00703c8afa1e017e7d433010 100644 (file)
@@ -1061,6 +1061,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
          return expr;
        /* else fall through...  */
 
+      case VECTOR_TYPE:
       case BOOLEAN_TYPE:
        return (desires & WANT_INT) ? expr : NULL_TREE;
       case ENUMERAL_TYPE:
index 624f145a206504df773590b45ff852e654c57ebb..bddae511ae64e32e37d6531daeb8e526875e3a63 100644 (file)
@@ -249,9 +249,11 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
   /* FIXME: Attributes.  */
   gcc_assert (ARITHMETIC_TYPE_P (t1) 
              || TREE_CODE (t1) == COMPLEX_TYPE
+             || TREE_CODE (t1) == VECTOR_TYPE
              || TREE_CODE (t1) == ENUMERAL_TYPE);
   gcc_assert (ARITHMETIC_TYPE_P (t2) 
              || TREE_CODE (t2) == COMPLEX_TYPE
+             || TREE_CODE (t1) == VECTOR_TYPE
              || TREE_CODE (t2) == ENUMERAL_TYPE);
 
   /* In what follows, we slightly generalize the rules given in [expr] so
@@ -278,6 +280,16 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
                                             attributes);
     }
 
+  if (code1 == VECTOR_TYPE)
+    {
+      /* When we get here we should have two vectors of the same size.
+        Just prefer the unsigned one if present.  */
+      if (TYPE_UNSIGNED (t1))
+       return build_type_attribute_variant (t1, attributes);
+      else
+       return build_type_attribute_variant (t2, attributes);
+    }
+
   /* If only one is real, use it as the result.  */
   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
     return build_type_attribute_variant (t1, attributes);
@@ -735,9 +747,9 @@ common_type (tree t1, tree t2)
   code2 = TREE_CODE (t2);
 
   if ((ARITHMETIC_TYPE_P (t1) || code1 == ENUMERAL_TYPE
-       || code1 == COMPLEX_TYPE)
+       || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
       && (ARITHMETIC_TYPE_P (t2) || code2 == ENUMERAL_TYPE
-         || code2 == COMPLEX_TYPE))
+         || code2 == COMPLEX_TYPE || code2 == VECTOR_TYPE))
     return type_after_usual_arithmetic_conversions (t1, t2);
 
   else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
@@ -2902,7 +2914,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     case BIT_AND_EXPR:
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
-      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+         || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE))
        shorten = -1;
       break;
 
@@ -3158,10 +3171,21 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       break;
     }
 
-  arithmetic_types_p = 
-    ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
-     && (code1 == INTEGER_TYPE || code1 == REAL_TYPE 
-        || code1 == COMPLEX_TYPE));
+  if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+       && (code1 == INTEGER_TYPE || code1 == REAL_TYPE 
+          || code1 == COMPLEX_TYPE)))
+    arithmetic_types_p = 1;
+  else
+    {
+      arithmetic_types_p = 0;
+      /* Vector arithmetic is only allowed when both sides are vectors.  */
+      if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+       {
+         if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)))
+           error ("can't convert between vector values of different size");
+         arithmetic_types_p = 1;
+       }
+    }
   /* Determine the RESULT_TYPE, if it is not already known.  */
   if (!result_type
       && arithmetic_types_p 
diff --git a/gcc/testsuite/g++.dg/conversion/simd2.C b/gcc/testsuite/g++.dg/conversion/simd2.C
new file mode 100644 (file)
index 0000000..a67df56
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+/* Test generic operations on vectors.  */
+
+int __attribute__((vector_size(16))) a, b, c;
+int __attribute__((vector_size(8))) d;
+void foo()
+{
+     a = b ^ c;
+     a = b + c;
+     a = b - c;
+     a = b * c;
+     a = b / c;
+     a = -b;
+     a = d + b;                /* { dg-error "can't convert between vector" } */
+}