Summary: 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 | 21 +++++++++++++++++++-- gcc/c/c-typeck.cc | 8 ++++++-- gcc/fold-const.cc | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index e0c4259c905..b3ca5219730 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 73e739c503d..f236fae94d4 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -2441,7 +2441,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; @@ -8360,10 +8376,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 == FIXED_POINT_TYPE)); + || c2 == COMPLEX_TYPE || c2 == FIXED_POINT_TYPE)); t1 = c_common_signed_type (t1); t2 = c_common_signed_type (t2); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index e55e887da14..25e7f68b5ab 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -4576,7 +4576,9 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, if (typecode == INTEGER_TYPE || typecode == BITINT_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; @@ -4599,7 +4601,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 dc05599c7fe..5c7b58136eb 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -11365,6 +11365,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