From ff2800ae6dc0286781c1c2c2380965ffc2362853 Mon Sep 17 00:00:00 2001
From: Robert Zakrzewski <robert.zakrzewski1@stellantis.com>
Date: Wed, 3 Apr 2024 07:30:17 +0200
Subject: [PATCH] Add _Float16, _Float32, _Float64 and __float128 support for
 jit

Fix _Float16 and __float128 support for jit. Add _Float32 and _Float64 support for jit

Add Float32 and Float54, update test-types.c
---
 gcc/jit/docs/topics/types.rst     |  8 ++++++
 gcc/jit/dummy-frontend.cc         | 16 +++++++++++
 gcc/jit/jit-common.h              |  2 +-
 gcc/jit/jit-playback.cc           | 28 +++++++++++++++++++
 gcc/jit/jit-recording.cc          | 40 +++++++++++++++++++++++++++
 gcc/jit/libgccjit.h               |  4 +++
 gcc/testsuite/jit.dg/test-types.c | 45 +++++++++++++++++++++++++++++++
 7 files changed, 142 insertions(+), 1 deletion(-)

diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
index bb51f037b7ea7..bcbe0d7e226f7 100644
--- a/gcc/jit/docs/topics/types.rst
+++ b/gcc/jit/docs/topics/types.rst
@@ -117,6 +117,14 @@ Standard types
        -
      * - :c:data:`GCC_JIT_TYPE_LONG_DOUBLE`
        -
+     * - :c:data:`GCC_JIT_TYPE_FLOAT16`
+       -
+     * - :c:data:`GCC_JIT_TYPE_FLOAT32`
+       -
+     * - :c:data:`GCC_JIT_TYPE_FLOAT64`
+       -
+     * - :c:data:`GCC_JIT_TYPE_FLOAT128`
+       -
      * - :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR`
        - C type: ``(const char *)``
      * - :c:data:`GCC_JIT_TYPE_SIZE_T`
diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc
index 8fdc108f6229f..e9e20a08ae878 100644
--- a/gcc/jit/dummy-frontend.cc
+++ b/gcc/jit/dummy-frontend.cc
@@ -1253,6 +1253,22 @@ recording::type* tree_type_to_jit_type (tree type)
   {
     return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_BFLOAT16);
   }
+  else if (type == float16_type_node)
+  {
+    return new recording::memento_of_get_type(&target_builtins_ctxt, GCC_JIT_TYPE_FLOAT16);
+  }
+  else if (type == float32_type_node)
+  {
+    return new recording::memento_of_get_type(&target_builtins_ctxt, GCC_JIT_TYPE_FLOAT32);
+  }
+  else if (type == float64_type_node)
+  {
+    return new recording::memento_of_get_type(&target_builtins_ctxt, GCC_JIT_TYPE_FLOAT64);
+  }
+  else if (type == float128_type_node)
+  {
+    return new recording::memento_of_get_type(&target_builtins_ctxt, GCC_JIT_TYPE_FLOAT128);
+  }
   else if (type == dfloat128_type_node)
   {
     return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index e724f77ae0fcd..a530333b27156 100644
--- a/gcc/jit/jit-common.h
+++ b/gcc/jit/jit-common.h
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #endif
 #endif
 
-const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_BFLOAT16 + 1;
+const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_FLOAT128 + 1;
 
 /* This comment is included by the docs.
 
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index cde058879a986..9bf805457625a 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -290,6 +290,34 @@ get_tree_node_for_type (enum gcc_jit_types type_)
       return double_type_node;
     case GCC_JIT_TYPE_LONG_DOUBLE:
       return long_double_type_node;
+    case GCC_JIT_TYPE_FLOAT16:
+      if (float16_type_node == NULL || TYPE_PRECISION(float16_type_node) != 16)
+      {
+        add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_);
+        return NULL;
+      }
+      return float16_type_node;
+    case GCC_JIT_TYPE_FLOAT32:
+      if (float32_type_node == NULL || TYPE_PRECISION(float32_type_node) != 32)
+      {
+        add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_);
+        return NULL;
+      }
+      return float32_type_node;
+    case GCC_JIT_TYPE_FLOAT64:
+      if (float64_type_node == NULL || TYPE_PRECISION(float64_type_node) != 64)
+      {
+        add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_);
+        return NULL;
+      }
+      return float64_type_node;
+    case GCC_JIT_TYPE_FLOAT128:
+      if (float128_type_node == NULL || TYPE_PRECISION(float128_type_node) != 128)
+      {
+        add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_);
+        return NULL;
+      }
+      return float128_type_node;
 
     case GCC_JIT_TYPE_SIZE_T:
       return size_type_node;
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index f0aae5c6d4d8c..e709872295a2c 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -2617,6 +2617,18 @@ recording::memento_of_get_type::get_size ()
     case GCC_JIT_TYPE_LONG_DOUBLE:
       size = LONG_DOUBLE_TYPE_SIZE;
       break;
+    case GCC_JIT_TYPE_FLOAT16:
+      size = 16;
+      break;
+    case GCC_JIT_TYPE_FLOAT32:
+      size = 32;
+      break;
+    case GCC_JIT_TYPE_FLOAT64:
+      size = 64;
+      break;
+    case GCC_JIT_TYPE_FLOAT128:
+      size = 128;
+      break;
     case GCC_JIT_TYPE_SIZE_T:
       /* Compare with tree.cc's build_common_tree_nodes.  */
       if (strcmp (SIZE_TYPE, "unsigned int") == 0)
@@ -2700,6 +2712,10 @@ recording::memento_of_get_type::dereference ()
     case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
+    case GCC_JIT_TYPE_FLOAT16:
+    case GCC_JIT_TYPE_FLOAT32:
+    case GCC_JIT_TYPE_FLOAT64:
+    case GCC_JIT_TYPE_FLOAT128:
     case GCC_JIT_TYPE_COMPLEX_FLOAT:
     case GCC_JIT_TYPE_COMPLEX_DOUBLE:
     case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
@@ -2765,6 +2781,10 @@ recording::memento_of_get_type::is_int () const
     case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
+    case GCC_JIT_TYPE_FLOAT16:
+    case GCC_JIT_TYPE_FLOAT32:
+    case GCC_JIT_TYPE_FLOAT64:
+    case GCC_JIT_TYPE_FLOAT128:
       return false;
 
     case GCC_JIT_TYPE_CONST_CHAR_PTR:
@@ -2824,6 +2844,10 @@ recording::memento_of_get_type::is_signed () const
     case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
+    case GCC_JIT_TYPE_FLOAT16:
+    case GCC_JIT_TYPE_FLOAT32:
+    case GCC_JIT_TYPE_FLOAT64:
+    case GCC_JIT_TYPE_FLOAT128:
 
     case GCC_JIT_TYPE_CONST_CHAR_PTR:
 
@@ -2884,6 +2908,10 @@ recording::memento_of_get_type::is_float () const
     case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
+    case GCC_JIT_TYPE_FLOAT16:
+    case GCC_JIT_TYPE_FLOAT32:
+    case GCC_JIT_TYPE_FLOAT64:
+    case GCC_JIT_TYPE_FLOAT128:
       return true;
 
     case GCC_JIT_TYPE_CONST_CHAR_PTR:
@@ -2948,6 +2976,10 @@ recording::memento_of_get_type::is_bool () const
     case GCC_JIT_TYPE_BFLOAT16:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
+    case GCC_JIT_TYPE_FLOAT16:
+    case GCC_JIT_TYPE_FLOAT32:
+    case GCC_JIT_TYPE_FLOAT64:
+    case GCC_JIT_TYPE_FLOAT128:
       return false;
 
     case GCC_JIT_TYPE_CONST_CHAR_PTR:
@@ -3026,6 +3058,10 @@ static const char * const get_type_strings[] = {
   "__int64_t",    /* GCC_JIT_TYPE_INT64_T */
   "__int128_t",   /* GCC_JIT_TYPE_INT128_T */
   "bfloat16",     /* GCC_JIT_TYPE_BFLOAT16 */
+  "_Float16",     /* GCC_JIT_TYPE_FLOAT16 */
+  "_Float32",     /* GCC_JIT_TYPE_FLOAT32 */
+  "_Float64",     /* GCC_JIT_TYPE_FLOAT64 */
+  "__float128",   /* GCC_JIT_TYPE_FLOAT128 */
 
 };
 
@@ -3073,6 +3109,10 @@ static const char * const get_type_enum_strings[] = {
   "GCC_JIT_TYPE_INT64_T",
   "GCC_JIT_TYPE_INT128_T",
   "GCC_JIT_TYPE_BFLOAT16",
+  "GCC_JIT_TYPE_FLOAT16",
+  "GCC_JIT_TYPE_FLOAT32",
+  "GCC_JIT_TYPE_FLOAT64",
+  "GCC_JIT_TYPE_FLOAT128",
 };
 
 void
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index d55a034f14aee..197e6382a1dd2 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -613,6 +613,10 @@ enum gcc_jit_types
   GCC_JIT_TYPE_INT128_T,
 
   GCC_JIT_TYPE_BFLOAT16,
+  GCC_JIT_TYPE_FLOAT16,
+  GCC_JIT_TYPE_FLOAT32,
+  GCC_JIT_TYPE_FLOAT64,
+  GCC_JIT_TYPE_FLOAT128,
 };
 
 extern gcc_jit_type *
diff --git a/gcc/testsuite/jit.dg/test-types.c b/gcc/testsuite/jit.dg/test-types.c
index 79f7ea21026fa..58a5a5305efec 100644
--- a/gcc/testsuite/jit.dg/test-types.c
+++ b/gcc/testsuite/jit.dg/test-types.c
@@ -50,6 +50,10 @@ struct zoo
   float m_float;
   double m_double;
   long double m_long_double;
+  _Float16 m_float16;
+  _Float32 m_float32;
+  _Float64 m_float64;
+  __float128 m_float128;
 
   const char *m_const_char_ptr;
 
@@ -156,6 +160,11 @@ create_code (gcc_jit_context *ctxt, void *user_data)
   gcc_jit_field *field_m_long_double =
     CREATE_FIELD (GCC_JIT_TYPE_LONG_DOUBLE, "m_long_double");
 
+  gcc_jit_field *field_m_float16 = CREATE_FIELD(GCC_JIT_TYPE_FLOAT16, "m_float16");
+  gcc_jit_field *field_m_float32 = CREATE_FIELD(GCC_JIT_TYPE_FLOAT32, "m_float32");
+  gcc_jit_field *field_m_float64 = CREATE_FIELD(GCC_JIT_TYPE_FLOAT64, "m_float64");
+  gcc_jit_field *field_m_float128 = CREATE_FIELD(GCC_JIT_TYPE_FLOAT128, "m_float128");
+
   gcc_jit_field *field_m_const_char_ptr =
     CREATE_FIELD (GCC_JIT_TYPE_CONST_CHAR_PTR, "m_const_char_ptr");
 
@@ -209,6 +218,11 @@ create_code (gcc_jit_context *ctxt, void *user_data)
     field_m_double,
     field_m_long_double,
 
+    field_m_float16,
+    field_m_float32,
+    field_m_float64,
+    field_m_float128,
+
     field_m_const_char_ptr,
 
     field_m_size_t,
@@ -398,6 +412,27 @@ create_code (gcc_jit_context *ctxt, void *user_data)
       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_DOUBLE),
       3.141))
 
+  ASSIGN(field_m_float16,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT16),
+      3.141))
+  ASSIGN(field_m_float32,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT32),
+      3.141))
+  ASSIGN(field_m_float64,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT64),
+      3.141))
+  ASSIGN(field_m_float128,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT128),
+      3.141))
+
   ASSIGN(field_m_const_char_ptr,
     gcc_jit_context_new_rvalue_from_ptr (
       ctxt,
@@ -479,6 +514,11 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
   CHECK_VALUE (z.m_double, 3.141);
   CHECK_VALUE (z.m_long_double, 3.141);
 
+  CHECK_VALUE (z.m_float16, (_Float16)3.141);
+  CHECK_VALUE (z.m_float32, (_Float32)3.141);
+  CHECK_VALUE (z.m_float64, (_Float64)3.141);
+  CHECK_VALUE (z.m_float128, (__float128)3.141);
+
   CHECK_VALUE (z.m_const_char_ptr, test_string);
 
   CHECK_VALUE (z.m_size_t, sizeof (struct zoo));
@@ -493,6 +533,11 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
   CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT)), sizeof (float));
   CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE)), sizeof (double));
 
+  CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT16)), sizeof(_Float16));
+  CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT32)), sizeof(_Float32));
+  CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT64)), sizeof(_Float64));
+  CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT128)), sizeof(__float128));
+
   gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
   gcc_jit_type *array_type1 = gcc_jit_context_new_array_type (ctxt, NULL, int_type, 2);
   gcc_jit_type *array_type2 = gcc_jit_context_new_array_type (ctxt, NULL, int_type, 2);