Commit cc27e657 by Paolo Bonzini Committed by Paolo Bonzini

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
parent d70bd7ff
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> 2004-05-04 Chris Demetriou <cgd@broadcom.com>
* config/mips/mips.c (override_options): Default to no * config/mips/mips.c (override_options): Default to no
......
...@@ -1277,6 +1277,16 @@ constant_fits_type_p (tree c, tree type) ...@@ -1277,6 +1277,16 @@ constant_fits_type_p (tree c, tree type)
return !TREE_OVERFLOW (c); 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. /* Convert EXPR to TYPE, warning about conversion problems with constants.
Invoke this function on every expression that is converted implicitly, Invoke this function on every expression that is converted implicitly,
i.e. because of language rules and not because of an explicit cast. */ i.e. because of language rules and not because of an explicit cast. */
......
...@@ -1257,6 +1257,8 @@ extern tree finish_label_address_expr (tree); ...@@ -1257,6 +1257,8 @@ extern tree finish_label_address_expr (tree);
different implementations. Used in c-common.c. */ different implementations. Used in c-common.c. */
extern tree lookup_label (tree); 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 rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
extern int c_safe_from_p (rtx, tree); extern int c_safe_from_p (rtx, tree);
......
...@@ -592,10 +592,8 @@ comptypes (tree type1, tree type2, int flags) ...@@ -592,10 +592,8 @@ comptypes (tree type1, tree type2, int flags)
break; break;
case VECTOR_TYPE: case VECTOR_TYPE:
/* The target might allow certain vector types to be compatible. */ val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
val = targetm.vector_opaque_p (t1) && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 0);
|| targetm.vector_opaque_p (t2)
|| TYPE_MODE (t1) == TYPE_MODE (t2);
break; break;
default: default:
...@@ -3292,7 +3290,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype, ...@@ -3292,7 +3290,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
} }
/* Some types can interconvert without explicit casts. */ /* Some types can interconvert without explicit casts. */
else if (codel == VECTOR_TYPE 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); return convert (type, rhs);
/* Arithmetic types all interconvert, and enum is treated like int. */ /* Arithmetic types all interconvert, and enum is treated like int. */
else if ((codel == INTEGER_TYPE || codel == REAL_TYPE else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
...@@ -3937,11 +3935,11 @@ digest_init (tree type, tree init, int require_constant) ...@@ -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 vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
below and handle as a constructor. */ below and handle as a constructor. */
if (code == VECTOR_TYPE 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)) && TREE_CONSTANT (inside_init))
{ {
if (TREE_CODE (inside_init) == VECTOR_CST 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), TYPE_MAIN_VARIANT (type),
COMPARE_STRICT)) COMPARE_STRICT))
return inside_init; return inside_init;
...@@ -4042,7 +4040,8 @@ digest_init (tree type, tree init, int require_constant) ...@@ -4042,7 +4040,8 @@ digest_init (tree type, tree init, int require_constant)
/* Handle scalar types, including conversions. */ /* Handle scalar types, including conversions. */
if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE 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 /* Note that convert_for_assignment calls default_conversion
for arrays and functions. We must not call it in the for arrays and functions. We must not call it in the
......
...@@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr) ...@@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr)
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
&& TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
&& ((*targetm.vector_opaque_p) (TREE_TYPE (to)) && vector_types_convertible_p (TREE_TYPE (to), TREE_TYPE (from)))
|| (*targetm.vector_opaque_p) (TREE_TYPE (from))))
conv = build_conv (ck_std, to, conv); conv = build_conv (ck_std, to, conv);
else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE) else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
|| (tcode == POINTER_TYPE && fcode == INTEGER_TYPE)) || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
...@@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr) ...@@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr)
conv->rank = cr_promotion; conv->rank = cr_promotion;
} }
else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
&& ((*targetm.vector_opaque_p) (from) && vector_types_convertible_p (from, to))
|| (*targetm.vector_opaque_p) (to)))
return build_conv (ck_std, to, conv); return build_conv (ck_std, to, conv);
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& is_properly_derived_from (from, to)) && is_properly_derived_from (from, to))
......
...@@ -1058,6 +1058,11 @@ comptypes (tree t1, tree t2, int strict) ...@@ -1058,6 +1058,11 @@ comptypes (tree t1, tree t2, int strict)
case COMPLEX_TYPE: case COMPLEX_TYPE:
return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)); 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: default:
break; break;
} }
...@@ -5600,8 +5605,7 @@ convert_for_assignment (tree type, tree rhs, ...@@ -5600,8 +5605,7 @@ convert_for_assignment (tree type, tree rhs,
coder = TREE_CODE (rhstype); coder = TREE_CODE (rhstype);
if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
&& ((*targetm.vector_opaque_p) (type) && vector_types_convertible_p (type, rhstype))
|| (*targetm.vector_opaque_p) (rhstype)))
return convert (type, rhs); return convert (type, rhs);
if (rhs == error_mark_node || rhstype == error_mark_node) if (rhs == error_mark_node || rhstype == error_mark_node)
......
2004-05-04 Paolo Bonzini <bonzini@gnu.org>
* g++.dg/ext/spe1.C: New testcase.
2004-05-04 Ziemowit Laski <zlaski@apple.com> 2004-05-04 Ziemowit Laski <zlaski@apple.com>
* objc.dg/image-info.m: Allow additional attributes * objc.dg/image-info.m: Allow additional attributes
......
/* { 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> { };
...@@ -5195,6 +5195,27 @@ finish_vector_type (tree t) ...@@ -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 /* 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 of C datatypes. The caller should call set_sizetype soon after calling
this function to select one of the types as sizetype. */ this function to select one of the types as sizetype. */
...@@ -5237,17 +5258,19 @@ build_common_tree_nodes (int signed_char) ...@@ -5237,17 +5258,19 @@ build_common_tree_nodes (int signed_char)
TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node; TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;
TYPE_PRECISION (boolean_type_node) = 1; TYPE_PRECISION (boolean_type_node) = 1;
intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode)); /* Fill in the rest of the sized types. Reuse existing type nodes
intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode)); when possible. */
intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode)); intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);
intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode)); intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);
unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode)); unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode)); 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_public_node = get_identifier ("public");
access_protected_node = get_identifier ("protected"); access_protected_node = get_identifier ("protected");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment