[PATCH] PR/14899: Recurse on comptypes for vector types.

Bonzini bonzini@gnu.org
Thu Apr 15 15:43:00 GMT 2004


This patch is an interim fix for PR target/14899 (the breakage
of Altivec's checks for signedness).  It includes a stricter
(and correct) definition of comptypes for vector types: this
definition comes from Richard Henderson's tentative patch to
redo AltiVec overloading, with a change for opaque vector
types that Aldy okay-ed in

http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00786.html

I also mutuated the make_or_reuse_type change in Richard's
patch, which is necessary to make

typedef int x __attribute__ ((vector_size (16));

compatible with Altivec vector types (which are created
from intSI_type_mode and not from int_type_mode) under the
new comptypes definition.

Bootstrapped/regtested i686-pc-linux-gnu.  A version without
the tree.c change bootstrapped/regtested with one failure on
powerpc-darwin; I checked manually that the tree.c hunk fixes
that one failure and that all other C and C++ AltiVec tests
still pass.

My AltiVec rewrite is going on pretty well.  The definitions
are in place (taken from current altivec.h).  I'll try
comparing the assembly output for the gcc testsuite,
as well as simtesting it, tomorrow or on Monday.  I'll
post the patch after the tree-ssa merge.

Paolo

2004-04-10  Paolo Bonzini  <bonzini@gnu.org>
	    Richard Henderson  <rth@redhat.com>

	PR target/14899

	* c-common.c (vector_types_compatible_p): New function.
	* c-typeck.c (comptypes): Recurse on vector types,
	treat a non-opaque type as equivalent to an opaque type.
	(convert_for_assignment): Use vector_types_compatible_p.
	(digest_init): Use vector_types_compatible_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, do not
	treat a non-opaque type as equivalent to an opaque type.
	(convert_for_assignment): Use vector_types_compatible_p.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.495
diff -u -p -r1.495 c-common.c
--- c-common.c	9 Apr 2004 20:08:02 -0000	1.495
+++ c-common.c	14 Apr 2004 10:00:33 -0000
@@ -1273,6 +1273,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_compatible_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: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.224
diff -u -p -r1.224 c-common.h
--- c-common.h	7 Apr 2004 20:47:50 -0000	1.224
+++ c-common.h	14 Apr 2004 10:00:33 -0000
@@ -1257,6 +1257,8 @@ extern tree finish_label_address_expr (t
    different implementations.  Used in c-common.c.  */
 extern tree lookup_label (tree);
 
+extern int vector_types_compatible_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: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.301
diff -u -p -r1.301 c-typeck.c
--- c-typeck.c	10 Apr 2004 18:47:49 -0000	1.301
+++ c-typeck.c	14 Apr 2004 10:00:34 -0000
@@ -592,10 +592,14 @@ comptypes (tree type1, tree type2, int f
       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);
+      /* This is a comparison of types.  If both of them are opaque,
+         the types are identical as long as their size is equal; else
+	 check if the underlying types are identical as well.  */
+      val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+            && (targetm.vector_opaque_p (t1)
+	        ? targetm.vector_opaque_p (t2)
+		: !targetm.vector_opaque_p (t2) 
+		  && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 0));
       break;
 
     default:
@@ -3292,7 +3296,7 @@ convert_for_assignment (tree type, tree 
     }
   /* Some types can interconvert without explicit casts.  */
   else if (codel == VECTOR_TYPE
-           && comptypes (type, TREE_TYPE (rhs), COMPARE_STRICT) == 1)
+           && vector_types_compatible_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 +3941,11 @@ digest_init (tree type, tree init, int r
      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_compatible_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 +4046,8 @@ digest_init (tree type, tree init, int r
   /* 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: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.367
diff -u -r1.367 tree.c
--- tree.c	12 Apr 2004 21:25:46 -0000	1.367
+++ tree.c	15 Apr 2004 12:56:11 -0000
@@ -5182,6 +5182,27 @@
   }
 }
 
+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.  */
@@ -5224,17 +5245,19 @@
   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");
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.473
diff -u -p -r1.473 call.c
--- cp/call.c	1 Apr 2004 03:50:37 -0000	1.473
+++ cp/call.c	14 Apr 2004 10:00:35 -0000
@@ -660,8 +660,7 @@ standard_conversion (tree to, tree from,
   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_compatible_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,
 	conv->rank = cr_promotion;
     }
   else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (from)
-	  || (*targetm.vector_opaque_p) (to)))
+	   && vector_types_compatible_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: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.539
diff -u -p -r1.539 typeck.c
--- cp/typeck.c	1 Apr 2004 23:14:47 -0000	1.539
+++ cp/typeck.c	14 Apr 2004 10:00:36 -0000
@@ -1058,6 +1058,17 @@ comptypes (tree t1, tree t2, int strict)
     case COMPLEX_TYPE:
       return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
 
+    case VECTOR_TYPE:
+      /* This is a comparison of types.  If both of them are opaque,
+	 the types are identical as long as their size is equal; else
+	 check if the underlying types are identical as well.  */
+      return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+	     && (targetm.vector_opaque_p (t1)
+	         ? targetm.vector_opaque_p (t2)
+	         : !targetm.vector_opaque_p (t2)
+		   && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)));
+      break;
+
     default:
       break;
     }
@@ -5600,8 +5611,7 @@ convert_for_assignment (tree type, tree 
   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_compatible_p (type, rhstype))
     return convert (type, rhs);
 
   if (rhs == error_mark_node || rhstype == error_mark_node)



More information about the Gcc-patches mailing list