From: Paolo Bonzini Date: Wed, 5 May 2004 07:23:00 +0000 (+0000) Subject: re PR target/14899 (wrong code due to change in compatibility rules for vector types) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cc27e657d36005a8b1672f2ee60a5ad779a0d804;p=gcc.git re PR target/14899 (wrong code due to change in compatibility rules for vector types) gcc/ChangeLog: 2004-05-04 Paolo Bonzini Richard Henderson 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 * g++.dg/ext/spe1.C: New testcase. Co-Authored-By: Richard Henderson From-SVN: r81504 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75470508f01..d82a2de9f02 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2004-05-04 Paolo Bonzini + Richard Henderson + + 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 * config/mips/mips.c (override_options): Default to no diff --git a/gcc/c-common.c b/gcc/c-common.c index c4f01292059..15d7e686841 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index 6e9099a3875..7a0a6e6ad39 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -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); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 2170222d769..c744cd6b131 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 56e089dd2e4..4f38c7ed622 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5544f2259d6..dedf4956b7e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2fe60262e8c..1cf06c4cb95 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-05-04 Paolo Bonzini + + * g++.dg/ext/spe1.C: New testcase. + 2004-05-04 Ziemowit Laski * 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 index 00000000000..b9ae5e7d135 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/spe1.C @@ -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 X { }; +template <> class X<__ev64_opaque__> { }; +template <> class X { }; diff --git a/gcc/tree.c b/gcc/tree.c index e7435a78a3c..0e159c3ca97 100644 --- a/gcc/tree.c +++ b/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)); - - 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");