Allow the creation and usage of builtins vectors of complex in C, using __attribute__ ((vector_size ()))
gcc/c-family/ChangeLog: * c-attribs.cc (vector_mode_valid_p): Add cases for vectors of complex (handle_mode_attribute): Likewise (type_valid_for_vector_size): Likewise * c-common.cc (c_common_type_for_mode): Likewise (vector_types_compatible_elements_p): Likewise gcc/ChangeLog: * fold-const.cc (fold_binary_loc): Likewise gcc/c/ChangeLog: * c-typeck.cc (build_unary_op): Likewise --- gcc/c-family/c-attribs.cc | 12 ++++++++++-- gcc/c-family/c-common.cc | 20 +++++++++++++++++++- gcc/c/c-typeck.cc | 8 ++++++-- gcc/fold-const.cc | 1 + 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index e2792ca6898..d4de85160c1 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -2019,6 +2019,8 @@ vector_mode_valid_p (machine_mode mode) /* Doh! What's going on? */ if (mclass != MODE_VECTOR_INT && mclass != MODE_VECTOR_FLOAT + && mclass != MODE_VECTOR_COMPLEX_INT + && mclass != MODE_VECTOR_COMPLEX_FLOAT && mclass != MODE_VECTOR_FRACT && mclass != MODE_VECTOR_UFRACT && mclass != MODE_VECTOR_ACCUM @@ -2125,6 +2127,8 @@ handle_mode_attribute (tree *node, tree name, tree args, case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: + case MODE_VECTOR_COMPLEX_INT: + case MODE_VECTOR_COMPLEX_FLOAT: case MODE_VECTOR_FRACT: case MODE_VECTOR_UFRACT: case MODE_VECTOR_ACCUM: @@ -4361,9 +4365,13 @@ type_valid_for_vector_size (tree type, tree atname, tree args, if ((!INTEGRAL_TYPE_P (type) && !SCALAR_FLOAT_TYPE_P (type) + && !COMPLEX_INTEGER_TYPE_P (type) + && !COMPLEX_FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) - || (!SCALAR_FLOAT_MODE_P (orig_mode) - && GET_MODE_CLASS (orig_mode) != MODE_INT + || ((!SCALAR_FLOAT_MODE_P (orig_mode) + && GET_MODE_CLASS (orig_mode) != MODE_INT) + && (!COMPLEX_FLOAT_MODE_P (orig_mode) + && GET_MODE_CLASS (orig_mode) != MODE_COMPLEX_INT) && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode)) || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)) || TREE_CODE (type) == BOOLEAN_TYPE) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 6ab63dae997..9574c074d26 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -2430,7 +2430,23 @@ c_common_type_for_mode (machine_mode mode, int unsignedp) : make_signed_type (precision)); } - if (COMPLEX_MODE_P (mode)) + if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL + && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) + { + unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode), + GET_MODE_NUNITS (mode)); + tree bool_type = build_nonstandard_boolean_type (elem_bits); + return build_vector_type_for_mode (bool_type, mode); + } + else if (VECTOR_MODE_P (mode) + && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) + { + machine_mode inner_mode = GET_MODE_INNER (mode); + tree inner_type = c_common_type_for_mode (inner_mode, unsignedp); + if (inner_type != NULL_TREE) + return build_vector_type_for_mode (inner_type, mode); + } + else if (COMPLEX_MODE_P (mode)) { machine_mode inner_mode; tree inner_type; @@ -8104,9 +8120,11 @@ vector_types_compatible_elements_p (tree t1, tree t2) gcc_assert ((INTEGRAL_TYPE_P (t1) || c1 == REAL_TYPE + || c1 == COMPLEX_TYPE || c1 == FIXED_POINT_TYPE) && (INTEGRAL_TYPE_P (t2) || c2 == REAL_TYPE + || c2 == COMPLEX_TYPE || c2 == FIXED_POINT_TYPE)); t1 = c_common_signed_type (t1); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 7cf411155c6..68a9646cf5b 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -4584,7 +4584,9 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, /* ~ works on integer types and non float vectors. */ if (typecode == INTEGER_TYPE || (gnu_vector_type_p (TREE_TYPE (arg)) - && !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg)))) + && !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg)) + && !COMPLEX_INTEGER_TYPE_P (TREE_TYPE (TREE_TYPE (arg))) + && !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (TREE_TYPE (arg))))) { tree e = arg; @@ -4607,7 +4609,9 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, if (!noconvert) arg = default_conversion (arg); } - else if (typecode == COMPLEX_TYPE) + else if (typecode == COMPLEX_TYPE + || COMPLEX_INTEGER_TYPE_P (TREE_TYPE (TREE_TYPE (arg))) + || COMPLEX_FLOAT_TYPE_P (TREE_TYPE (TREE_TYPE (arg)))) { code = CONJ_EXPR; pedwarn (location, OPT_Wpedantic, diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index f1224b6a548..9e9f711e82d 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -11109,6 +11109,7 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, to __complex__ ( x, y ). This is not the same for SNaNs or if signed zeros are involved. */ if (!HONOR_SNANS (arg0) + && !(VECTOR_TYPE_P (TREE_TYPE (arg0))) && !HONOR_SIGNED_ZEROS (arg0) && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))) { -- 2.17.1