[v2,08/11] Native complex ops: Add explicit vector of complex

Message ID 20230912100713.1074-9-snoiry@kalrayinc.com
State Unresolved
Headers
Series Native complex operations |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Sylvain Noiry Sept. 12, 2023, 10:07 a.m. UTC
  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(-)
  

Comments

Joseph Myers Sept. 12, 2023, 5:25 p.m. UTC | #1
On Tue, 12 Sep 2023, Sylvain Noiry via Gcc-patches wrote:

> Summary:
> Allow the creation and usage of builtins vectors of complex
> in C, using __attribute__ ((vector_size ()))

If you're adding a new language feature like this, you need to update 
extend.texi to explain the valid uses of the attribute for complex types, 
and (under "Vector Extensions") the valid uses of the resulting vectors.  
You also need to add testcases to the testsuite for such vectors - both 
execution tests covering valid uses of the vectors, and tests that invalid 
declarations or uses of such vectors (uses with any operator, or other 
operand to such operator, that aren't valid) are properly rejected - go 
through all cases of operators, with one or two complex vector operands, 
of the same or different types, and with different choices for what type 
the other operand might be when one has complex vector type, and make sure 
they are all properly tested and do have the desired and documented 
semantics.

If the intended semantics are the same for C and C++, the tests should be 
c-c++-common tests.  Any cases where the intended semantics are different 
will need separate tests for each language or appropriately conditional 
test assertions in c-c++-common.
  
Richard Biener Sept. 13, 2023, 6:48 a.m. UTC | #2
On Tue, Sep 12, 2023 at 7:26 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Tue, 12 Sep 2023, Sylvain Noiry via Gcc-patches wrote:
>
> > Summary:
> > Allow the creation and usage of builtins vectors of complex
> > in C, using __attribute__ ((vector_size ()))
>
> If you're adding a new language feature like this, you need to update
> extend.texi to explain the valid uses of the attribute for complex types,
> and (under "Vector Extensions") the valid uses of the resulting vectors.
> You also need to add testcases to the testsuite for such vectors - both
> execution tests covering valid uses of the vectors, and tests that invalid
> declarations or uses of such vectors (uses with any operator, or other
> operand to such operator, that aren't valid) are properly rejected - go
> through all cases of operators, with one or two complex vector operands,
> of the same or different types, and with different choices for what type
> the other operand might be when one has complex vector type, and make sure
> they are all properly tested and do have the desired and documented
> semantics.
>
> If the intended semantics are the same for C and C++, the tests should be
> c-c++-common tests.  Any cases where the intended semantics are different
> will need separate tests for each language or appropriately conditional
> test assertions in c-c++-common.

And to add - in other related discussions we always rejected adding vector types
of composite types.  I realize that if the hardware supports vector complex
arithmetic instructions this might be the first true good reason to allow these.

Richard.

> --
> Joseph S. Myers
> joseph@codesourcery.com
  

Patch

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)))
 	    {