re PR target/14899 (wrong code due to change in compatibility rules for vector types)

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
This commit is contained in:
Paolo Bonzini 2004-05-05 07:23:00 +00:00 committed by Paolo Bonzini
parent d70bd7fff0
commit cc27e657d3
9 changed files with 93 additions and 24 deletions

View 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

View 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. */

View 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);

View 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

View 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))

View 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)

View 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

View File

@ -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> { };

View 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));
/* 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_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));
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");