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:
parent
d70bd7fff0
commit
cc27e657d3
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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> { };
|
43
gcc/tree.c
43
gcc/tree.c
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue