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