]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libgccjit: Add _Float16, _Float32, _Float64 and __float128 support for jit
authorAntoni Boucher <bouanto@zoho.com>
Fri, 19 Sep 2025 12:44:04 +0000 (08:44 -0400)
committerAntoni Boucher <bouanto@zoho.com>
Wed, 22 Oct 2025 00:39:54 +0000 (20:39 -0400)
gcc/ChangeLog:

* config/i386/i386-jit.cc: Mark new float types as supported.

gcc/jit/ChangeLog:

* docs/topics/types.rst: Document new types.
* dummy-frontend.cc: Support new types in tree_type_to_jit_type.
* jit-common.h: Update NUM_GCC_JIT_TYPES.
* jit-playback.cc: Support new types in get_tree_node_for_type.
* jit-recording.cc: Support new types.
* libgccjit.h (gcc_jit_types): Add new types.

gcc/testsuite/ChangeLog:

* jit.dg/all-non-failing-tests.h: Mention new test.
* jit.dg/test-sized-float.c: New test.

gcc/config/i386/i386-jit.cc
gcc/jit/docs/topics/types.rst
gcc/jit/dummy-frontend.cc
gcc/jit/jit-common.h
gcc/jit/jit-playback.cc
gcc/jit/jit-recording.cc
gcc/jit/libgccjit.h
gcc/testsuite/jit.dg/all-non-failing-tests.h
gcc/testsuite/jit.dg/test-sized-float.c [new file with mode: 0644]

index c1e2929a4735694b4eeb9bda497fba6938904822..73ca5905c18b57002e1e31f0296ad47a9da77728 100644 (file)
@@ -65,6 +65,18 @@ ix86_jit_register_target_info (void)
     jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_INT128_T);
   }
 
+  if (float16_type_node != NULL && TYPE_PRECISION (float16_type_node) == 16)
+    jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT16);
+
+  if (float32_type_node != NULL && TYPE_PRECISION (float32_type_node) == 32)
+    jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT32);
+
+  if (float64_type_node != NULL && TYPE_PRECISION (float64_type_node) == 64)
+    jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT64);
+
+  if (float128_type_node != NULL && TYPE_PRECISION (float128_type_node) == 128)
+    jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT128);
+
 #define ADD_TARGET_INFO jit_add_target_info
 #include "i386-rust-and-jit.inc"
 #undef ADD_TARGET_INFO
index 92830652913e1028939d5ce4936ba1415d7b5c57..ae4d7d4e28530e74115a04f4c229b758661d0e1a 100644 (file)
@@ -119,6 +119,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`
index faf9d036350ff083003a2954dea707c0a76cf89f..0668d67099f5f135885e3eb535d10836d74b997e 100644 (file)
@@ -1195,12 +1195,6 @@ recording::type* tree_type_to_jit_type (tree type)
     // FIXME: wrong type.
     return new recording::memento_of_get_type (&target_builtins_ctxt,
                                               GCC_JIT_TYPE_VOID);
-  /* TODO: Remove when we add support for sized floating-point types.  */
-  for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
-    if (type == FLOATN_NX_TYPE_NODE (i))
-      // FIXME: wrong type.
-      return new recording::memento_of_get_type (&target_builtins_ctxt,
-                                                GCC_JIT_TYPE_VOID);
   if (type == void_type_node)
     return new recording::memento_of_get_type (&target_builtins_ctxt,
                                               GCC_JIT_TYPE_VOID);
@@ -1266,6 +1260,26 @@ recording::type* tree_type_to_jit_type (tree type)
   else if (type == bfloat16_type_node)
     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)
     // FIXME: wrong type.
     return new recording::memento_of_get_type (&target_builtins_ctxt,
index 8c07f557d0cb0ad0b68ae9dbd6a4d08cb1bd6d9e..e32bd881b828d8c2c75c20d039847e5bdb1a80e3 100644 (file)
@@ -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.
 
index d5145d0e7cd1f024aeda8f37609f8bb22a8760d5..00d5e7290edecc0d740ae9d8d0d8d8101f97c431 100644 (file)
@@ -295,6 +295,39 @@ 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;
index 754ccb2b1c63dd83548135584c1527ce21bf69ea..6816a71dcd81e693bb3a9f39e133c619bc3b11f6 100644 (file)
@@ -2662,6 +2662,18 @@ recording::memento_of_get_type::get_size ()
       m = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE);
       size = GET_MODE_PRECISION (m).to_constant ();
       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:
       size = MAX_BITS_PER_WORD;
       break;
@@ -2718,6 +2730,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:
@@ -2783,6 +2799,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:
@@ -2842,6 +2862,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:
 
@@ -2902,6 +2926,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:
@@ -2966,6 +2994,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:
@@ -3043,8 +3075,11 @@ static const char * const get_type_strings[] = {
   "__int32_t",    /* GCC_JIT_TYPE_INT32_T */
   "__int64_t",    /* GCC_JIT_TYPE_INT64_T */
   "__int128_t",   /* GCC_JIT_TYPE_INT128_T */
-
-  "bfloat16", /* GCC_JIT_TYPE_BFLOAT16 */
+  "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 */
 };
 
 /* Implementation of recording::memento::make_debug_string for
@@ -3091,6 +3126,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
index f71ed630589a6eab2e021d229d8fa772d83fb5e0..1cc5e6a9946c2953bc50eb2d76c8d5d01c6b9643 100644 (file)
@@ -619,6 +619,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 *
index dc98ad24526c5b6490d877688aa7fbf1c6c5ad2f..fe9ad1da3f4d84b201823466cecfffb70f6fc8ba 100644 (file)
 #undef create_code
 #undef verify_code
 
+/* test-sized-float.c */
+#define create_code create_code_sized_float
+#define verify_code verify_code_sized_float
+#include "test-sized-float.c"
+#undef create_code
+#undef verify_code
+
 /* test-target-builtins.c: This can't be in the testcases array as it
    is target-specific.  */
 
@@ -638,6 +645,9 @@ const struct testcase testcases[] = {
   {"sizeof",
    create_code_sizeof,
    verify_code_sizeof},
+  {"sized-float",
+   create_code_sized_float,
+   verify_code_sized_float},
   {"string_literal",
    create_code_string_literal,
    verify_code_string_literal},
diff --git a/gcc/testsuite/jit.dg/test-sized-float.c b/gcc/testsuite/jit.dg/test-sized-float.c
new file mode 100644 (file)
index 0000000..fc90f14
--- /dev/null
@@ -0,0 +1,167 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+struct float_zoo
+{
+  _Float16 m_float16;
+  _Float32 m_float32;
+  _Float64 m_float64;
+  __float128 m_float128;
+};
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to inject the equivalent of:
+
+     void
+     test_caller (struct float_zoo *z)
+     {
+       for each fields "m_field":
+         z->m_field = ...some data;
+     }
+  */
+  gcc_jit_type *void_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+#define CREATE_FIELD(TYPE, NAME) \
+  gcc_jit_context_new_field ( \
+       ctxt, NULL, \
+       gcc_jit_context_get_type (ctxt, TYPE), \
+       NAME)
+
+  gcc_jit_context *info_ctxt = gcc_jit_context_acquire ();
+  gcc_jit_target_info *target_info = gcc_jit_context_get_target_info (info_ctxt);
+
+  enum gcc_jit_types float_type1 = GCC_JIT_TYPE_FLOAT;
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16))
+    float_type1 = GCC_JIT_TYPE_FLOAT16;
+
+  enum gcc_jit_types float_type2 = GCC_JIT_TYPE_FLOAT;
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32))
+    float_type2 = GCC_JIT_TYPE_FLOAT32;
+
+  enum gcc_jit_types float_type3 = GCC_JIT_TYPE_FLOAT;
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64))
+    float_type3 = GCC_JIT_TYPE_FLOAT64;
+
+  enum gcc_jit_types float_type4 = GCC_JIT_TYPE_FLOAT;
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128))
+    float_type4 = GCC_JIT_TYPE_FLOAT128;
+
+  gcc_jit_field *field_m_float16 = CREATE_FIELD(float_type1, "m_float16");
+  gcc_jit_field *field_m_float32 = CREATE_FIELD(float_type2, "m_float32");
+  gcc_jit_field *field_m_float64 = CREATE_FIELD(float_type3, "m_float64");
+  gcc_jit_field *field_m_float128 = CREATE_FIELD(float_type4, "m_float128");
+
+#undef CREATE_FIELD
+
+  gcc_jit_field *zoo_fields[] = {
+    field_m_float16,
+    field_m_float32,
+    field_m_float64,
+    field_m_float128,
+  };
+
+  gcc_jit_type *zoo_type =
+    gcc_jit_struct_as_type (
+      gcc_jit_context_new_struct_type (
+        ctxt,
+       NULL,
+       "float_zoo",
+       sizeof (zoo_fields) / sizeof (zoo_fields[0]),
+       zoo_fields));
+
+  gcc_jit_type *zoo_ptr_type =
+    gcc_jit_type_get_pointer (zoo_type);
+
+  /* Build the test_fn.         */
+  gcc_jit_param *param_z =
+    gcc_jit_context_new_param (ctxt, NULL, zoo_ptr_type, "z");
+  gcc_jit_function *test_fn =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                 GCC_JIT_FUNCTION_EXPORTED,
+                                 void_type,
+                                 "test_float_types",
+                                 1, &param_z,
+                                 0);
+  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+
+  /* Write to the various fields of param "z". */
+#define ASSIGN(FIELD, EXPR) \
+  gcc_jit_block_add_assignment (               \
+    block, NULL,                               \
+    gcc_jit_rvalue_dereference_field (         \
+      gcc_jit_param_as_rvalue (param_z),       \
+      NULL,                                    \
+      (FIELD)),                                \
+    (EXPR));
+
+  ASSIGN(field_m_float16,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, float_type1),
+      3.141))
+  ASSIGN(field_m_float32,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, float_type2),
+      3.141))
+  ASSIGN(field_m_float64,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, float_type3),
+      3.141))
+  ASSIGN(field_m_float128,
+    gcc_jit_context_new_rvalue_from_double (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, float_type4),
+      3.141))
+
+#undef ASSIGN
+
+  gcc_jit_block_end_with_void_return (block, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  typedef void (*fn_type) (struct float_zoo *);
+  CHECK_NON_NULL (result);
+
+  fn_type test_float_types =
+    (fn_type)gcc_jit_result_get_code (result, "test_float_types");
+  CHECK_NON_NULL (test_float_types);
+
+  struct float_zoo z;
+  memset (&z, 0xf0, sizeof (z));
+
+  /* Call the JIT-generated function.  */
+  test_float_types (&z);
+
+  /* Verify that it correctly wrote to the various fields.  */
+  gcc_jit_context *info_ctxt = gcc_jit_context_acquire ();
+  gcc_jit_target_info *target_info = gcc_jit_context_get_target_info (info_ctxt);
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16))
+    CHECK_VALUE (z.m_float16, (_Float16)3.141);
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32))
+    CHECK_VALUE (z.m_float32, (_Float32)3.141);
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64))
+    CHECK_VALUE (z.m_float64, (_Float64)3.141);
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128))
+    CHECK_VALUE (z.m_float128, (__float128)3.141);
+
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16))
+    CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT16)), sizeof (_Float16));
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32))
+    CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT32)), sizeof (_Float32));
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64))
+    CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT64)), sizeof (_Float64));
+  if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128))
+    CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT128)), sizeof (__float128));
+}