re PR target/14899 (wrong code due to change in compatibility rules for vector types)
authorPaolo Bonzini <bonzini@gnu.org>
Wed, 5 May 2004 07:23:00 +0000 (07:23 +0000)
committerPaolo Bonzini <bonzini@gcc.gnu.org>
Wed, 5 May 2004 07:23:00 +0000 (07:23 +0000)
gcc/ChangeLog:
2004-05-04  Paolo Bonzini  <bonzini@gnu.org>
            Richard Henderson  <rth@redhat.com>

        PR target/14899

        * c-common.c (vector_types_convertible_p): New function.
        * c-typeck.c (comptypes): Recurse on vector types.
        (convert_for_assignment): Use vector_types_convertible_p.
        (digest_init): Use vector_types_convertible_p to check
        validness of constant vector initializers; otherwise treat
        them as scalars.
        * tree.c (make_or_reuse_type): New.
        (build_common_tree_nodes): Use it.
        * cp/call.c (standard_conversion): Likewise.
        * cp/typeck.c (comptypes): Recurse on vector types.
        (convert_for_assignment): Use vector_types_convertible_p.
        * config/rs6000/rs6000.c (build_opaque_vector_type):
        New function.
        (rs6000_init_builtins): Use it.

gcc/testsuite/ChangeLog:
2004-05-04  Paolo Bonzini  <bonzini@gnu.org>

* g++.dg/ext/spe1.C: New testcase.

Co-Authored-By: Richard Henderson <rth@redhat.com>
From-SVN: r81504

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

index 75470508f01ae85f03119799fb8b843800c28506..d82a2de9f024bf21e8ae8cf550efac24027d50f2 100644 (file)
@@ -1,3 +1,23 @@
+2004-05-04  Paolo Bonzini  <bonzini@gnu.org>
+           Richard Henderson  <rth@redhat.com>
+
+       PR target/14899
+
+       * c-common.c (vector_types_convertible_p): New function.
+       * c-typeck.c (comptypes): Recurse on vector types.
+       (convert_for_assignment): Use vector_types_convertible_p.
+       (digest_init): Use vector_types_convertible_p to check
+       validness of constant vector initializers; otherwise treat
+       them as scalars.
+       * tree.c (make_or_reuse_type): New.
+       (build_common_tree_nodes): Use it.
+       * cp/call.c (standard_conversion): Likewise.
+       * cp/typeck.c (comptypes): Recurse on vector types.
+       (convert_for_assignment): Use vector_types_convertible_p.
+       * config/rs6000/rs6000.c (build_opaque_vector_type):
+       New function.
+       (rs6000_init_builtins): Use it.
+
 2004-05-04  Chris Demetriou  <cgd@broadcom.com>
 
        * config/mips/mips.c (override_options): Default to no
index c4f012920590e3f4c940c296e39e05ea97cd4021..15d7e686841bb0ec678901f74264d5728d839694 100644 (file)
@@ -1277,6 +1277,16 @@ constant_fits_type_p (tree c, tree type)
   return !TREE_OVERFLOW (c);
 }
 
+/* Nonzero if vector types T1 and T2 can be converted to each other
+   without an explicit cast.  */
+int
+vector_types_convertible_p (tree t1, tree t2)
+{
+  return targetm.vector_opaque_p (t1)
+        || targetm.vector_opaque_p (t2)
+        || TYPE_MODE (t1) == TYPE_MODE (t2);
+}
+
 /* Convert EXPR to TYPE, warning about conversion problems with constants.
    Invoke this function on every expression that is converted implicitly,
    i.e. because of language rules and not because of an explicit cast.  */
index 6e9099a38757820a4b3f22171c37d6e27f84da87..7a0a6e6ad39a67a2dcdce3df2d1d264da5d8c387 100644 (file)
@@ -1257,6 +1257,8 @@ extern tree finish_label_address_expr (tree);
    different implementations.  Used in c-common.c.  */
 extern tree lookup_label (tree);
 
+extern int vector_types_convertible_p (tree t1, tree t2);
+
 extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
 
 extern int c_safe_from_p (rtx, tree);
index 2170222d7695bbdaeeb817f5e55f0b3658ad3d85..c744cd6b131b9ef027c074d6b6329de1c7792e3e 100644 (file)
@@ -592,10 +592,8 @@ comptypes (tree type1, tree type2, int flags)
       break;
 
     case VECTOR_TYPE:
-      /* The target might allow certain vector types to be compatible.  */
-      val = targetm.vector_opaque_p (t1)
-       || targetm.vector_opaque_p (t2)
-       || TYPE_MODE (t1) == TYPE_MODE (t2);
+      val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+           && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 0);
       break;
 
     default:
@@ -3292,7 +3290,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
     }
   /* Some types can interconvert without explicit casts.  */
   else if (codel == VECTOR_TYPE
-           && comptypes (type, TREE_TYPE (rhs), COMPARE_STRICT) == 1)
+           && vector_types_convertible_p (type, TREE_TYPE (rhs)))
     return convert (type, rhs);
   /* Arithmetic types all interconvert, and enum is treated like int.  */
   else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
@@ -3937,11 +3935,11 @@ digest_init (tree type, tree init, int require_constant)
      vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
      below and handle as a constructor.  */
     if (code == VECTOR_TYPE
-        && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
+        && vector_types_convertible_p (TREE_TYPE (inside_init), type)
         && TREE_CONSTANT (inside_init))
       {
        if (TREE_CODE (inside_init) == VECTOR_CST
-           && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+            && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
                          TYPE_MAIN_VARIANT (type),
                          COMPARE_STRICT))
          return inside_init;
@@ -4042,7 +4040,8 @@ digest_init (tree type, tree init, int require_constant)
   /* Handle scalar types, including conversions.  */
 
   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
-      || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE)
+      || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
+      || code == VECTOR_TYPE)
     {
       /* Note that convert_for_assignment calls default_conversion
         for arrays and functions.  We must not call it in the
index 56e089dd2e4a849efb446c8ba44ba8d2f7932c58..4f38c7ed6227fa5ba7e6862708825a11e29f03d9 100644 (file)
@@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr)
   else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
           && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
           && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
-          && ((*targetm.vector_opaque_p) (TREE_TYPE (to))
-              || (*targetm.vector_opaque_p) (TREE_TYPE (from))))
+          && vector_types_convertible_p (TREE_TYPE (to), TREE_TYPE (from)))
     conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
           || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
@@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr)
        conv->rank = cr_promotion;
     }
   else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (from)
-         || (*targetm.vector_opaque_p) (to)))
+          && vector_types_convertible_p (from, to))
     return build_conv (ck_std, to, conv);
   else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
           && is_properly_derived_from (from, to))
index 5544f2259d6b2f0d00375cc40dc5aede36a5e5e5..dedf4956b7e477b144d49d9403bf67e1b9326735 100644 (file)
@@ -1058,6 +1058,11 @@ comptypes (tree t1, tree t2, int strict)
     case COMPLEX_TYPE:
       return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
 
+    case VECTOR_TYPE:
+      return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+            && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
+      break;
+
     default:
       break;
     }
@@ -5600,8 +5605,7 @@ convert_for_assignment (tree type, tree rhs,
   coder = TREE_CODE (rhstype);
 
   if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (type)
-         || (*targetm.vector_opaque_p) (rhstype)))
+      && vector_types_convertible_p (type, rhstype))
     return convert (type, rhs);
 
   if (rhs == error_mark_node || rhstype == error_mark_node)
index 2fe60262e8ce4e04abbf4dfa6f40aa97feacf4e5..1cf06c4cb95872d688678cb8e41d2ebf8640266b 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-04  Paolo Bonzini  <bonzini@gnu.org>
+
+       * g++.dg/ext/spe1.C: New testcase.
+
 2004-05-04  Ziemowit Laski  <zlaski@apple.com>
 
        * objc.dg/image-info.m: Allow additional attributes
diff --git a/gcc/testsuite/g++.dg/ext/spe1.C b/gcc/testsuite/g++.dg/ext/spe1.C
new file mode 100644 (file)
index 0000000..b9ae5e7
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-options "-mcpu=8540 -mabi=spe -O0" } */
+
+typedef int v2si __attribute__ ((vector_size (8)));
+
+/* The two specializations must be considered different.  */
+template <class T> class X                 { };
+template <>        class X<__ev64_opaque__> { };
+template <>        class X<v2si>           { };
index e7435a78a3c9d58be2ce0f4c1023b22a352b8fdb..0e159c3ca9710cfe529fc3cd0a52735c0ca12447 100644 (file)
@@ -5195,6 +5195,27 @@ finish_vector_type (tree t)
   }
 }
 
+static tree
+make_or_reuse_type (unsigned size, int unsignedp)
+{
+  if (size == INT_TYPE_SIZE)
+    return unsignedp ? unsigned_type_node : integer_type_node;
+  if (size == CHAR_TYPE_SIZE)
+    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+  if (size == SHORT_TYPE_SIZE)
+    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+  if (size == LONG_TYPE_SIZE)
+    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+  if (size == LONG_LONG_TYPE_SIZE)
+    return (unsignedp ? long_long_unsigned_type_node
+            : long_long_integer_type_node);
+
+  if (unsignedp)
+    return make_unsigned_type (size);
+  else
+    return make_signed_type (size);
+}
+
 /* Create nodes for all integer types (and error_mark_node) using the sizes
    of C datatypes.  The caller should call set_sizetype soon after calling
    this function to select one of the types as sizetype.  */
@@ -5237,17 +5258,19 @@ build_common_tree_nodes (int signed_char)
   TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;
   TYPE_PRECISION (boolean_type_node) = 1;
 
-  intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode));
-  intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
-  intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
-  intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
-  intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
-
-  unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
-  unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
-  unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
-  unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
-  unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+  /* Fill in the rest of the sized types.  Reuse existing type nodes
+     when possible.  */
+  intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
+  intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);
+  intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
+  intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
+  intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);
+
+  unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
+  unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
+  unsigned_intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 1);
+  unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1);
+  unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1);
   
   access_public_node = get_identifier ("public");
   access_protected_node = get_identifier ("protected");