public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
From: Petter Tomner <tomner@bahnhof.se>
To: David Malcolm <dmalcolm@redhat.com>, jit@gcc.gnu.org
Subject: Re: [PATCH 2/2] jit: Complex types and loong constants
Date: Mon, 27 Nov 2023 00:15:34 +0100	[thread overview]
Message-ID: <e7594ba2-6e21-4b6d-a568-cc2d4b2d4d3c@bahnhof.se> (raw)
In-Reply-To: <6dee747a8195d1381fcd7c2455633cdaf53a1c32.camel@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1062 bytes --]

> Or we could simply require the user to use C99/C++11 for generated
> reproducers.  That's probably simplest.

I think that is fine. It's a debugging and test tool anyway.

I added the following include guards for long long (in the first patch of the series):

+#ifdef __GNUC__
+
+/* Include entrypoints with long long parameter types. */
+#  define LIBGCCJIT_INCLUDE_LONGLONGS
+
+#else
+
+#  if __STDC_VERSION__ >= 199901L
+#    define LIBGCCJIT_INCLUDE_LONGLONGS
+#  elif __cplusplus >= 201103L
+#    define LIBGCCJIT_INCLUDE_LONGLONGS
+#  endif
+
+#endif
+

> "arr" should probably be const, and "len" be a size_t.

+reproducer_write_arr (reproducer &r, const unsigned char *arr, size_t len)

> FWIW "LIBGCCJIT_HAVE_LONGLONG_CONSTANTS" doesn't seem quite like the
> right name here, but I wasn't able to come up with a better one.

I changed it to LIBGCCJIT_HAVE_LOONG_CONSTANTS. I think it better conveys
it is long long, _Complex long double and long double.

> Is this a typo for "typepunning"...

+/* For typepunning NaNs. */


make check-jit runs fine.

[-- Attachment #2: 0002-long-long.patch --]
[-- Type: text/x-patch, Size: 41642 bytes --]

From cc7f894268ddb3dbb9d12b7b0b99b56307d05d3b Mon Sep 17 00:00:00 2001
From: Petter Tomner <tomner@bahnhof.se>
Date: Sat, 16 Oct 2021 21:55:20 +0200
Subject: [PATCH 2/2] long long

JIT: Add long long, long double and complex long double constants

This patch adds entrypoints to make constants (literals) for long long,
long double and complex long double types.

long long entrypoint only included for compilers that claim to be gcc
compatible or claim proper C or C++ std versions for the long long type.

Also, it fixes problems with all floating point numbers in write_reproducer.
I.e. support NAN and INF values, aswell as proper precision for double
and long double. Which is needed for testing this patch.

Signed-off-by:
2021-10-21  Petter Tomner  <tomner@bahnhof.se>

gcc/jit/
	* jit-playback.c :
	(new_rvalue_from_const <long long>): New
	(new_rvalue_from_const <long>): Uses long long instead
	(new_rvalue_from_const <long double>): New
	(new_rvalue_from_const <host_pair<long double>>) : New
	* jit-recording.c :
	(dump_reproducer_to_file) : Type punning NANs
	(reproducer_write_arr) : arr -> "char array literal"-string
	(memento_of_new_rvalue_from_const <long long>) : New
	(memento_of_new_rvalue_from_const <long double>) : New
	(memento_of_new_rvalue_from_const <host_pair<long double>>) : New
	(memento_of_new_rvalue_from_const <double>::make_debug_string):
	%g instead of %f
	(memento_of_new_rvalue_from_const <double>::write_reproducer):
	%a instead of %f, handle NAN and INF
	(memento_of_new_rvalue_from_const<host_pair<double>>::write_reproducer):
	%a instead of %f, handle NAN and INF. Use CMPLX macro.
	* libgccjit.c :
	* libgccjit.h :
	(LIBGCCJIT_HAVE_LONGLONG_CONSTANTS) : New
	(gcc_jit_context_new_rvalue_from_long_long) : New
	(gcc_jit_context_new_rvalue_from_long_double) : New
	(gcc_jit_context_new_rvalue_from_complex_long_double) : New
	* libgccjit++.h : New entrypoints
	* libgccjit.map: New entrypoints added to ABI 26

gcc/testsuite/
	* jit.dg/all-non-failing-tests.h: Added test-long-literals.c
	* jit.dg/test-long-literals.c: New

gcc/jit/docs/topics/
	* compatibility.rst : Updated docs
	* expressions.rst
---
 gcc/jit/docs/topics/compatibility.rst        |   6 +-
 gcc/jit/docs/topics/expressions.rst          |  48 ++-
 gcc/jit/jit-playback.cc                      | 144 ++++++-
 gcc/jit/jit-recording.cc                     | 391 ++++++++++++++++++-
 gcc/jit/libgccjit++.h                        |  28 ++
 gcc/jit/libgccjit.cc                         |  48 +++
 gcc/jit/libgccjit.h                          |  38 +-
 gcc/jit/libgccjit.map                        |   4 +
 gcc/testsuite/jit.dg/all-non-failing-tests.h |   7 +
 gcc/testsuite/jit.dg/test-long-literals.c    | 274 +++++++++++++
 10 files changed, 968 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-long-literals.c

diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 6922a2f67e9..e8b16926330 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -384,13 +384,15 @@ alignment of a variable:
 ``LIBGCCJIT_ABI_26``
 --------------------
 ``LIBGCCJIT_ABI_26`` covers the addition of support for complex types,
-literals for complex types as well as the
+literals for long long, long double and complex types as well as the
 complex binary operator.
 
 Note that :c:macro:`GCC_JIT_TYPE_COMPLEX_FLOAT` etc. existed in earlier
 ABI:s, but were not functional.
 
   *  :func:`gcc_jit_context_new_rvalue_from_complex_double`
+  *  :func:`gcc_jit_context_new_rvalue_from_complex_long_double`
+  *  :func:`gcc_jit_context_new_rvalue_from_long_double`
+  *  :func:`gcc_jit_context_new_rvalue_from_long_long`
   *  :func:`gcc_jit_context_set_bool_enable_complex_types`
   *  :c:macro:`GCC_JIT_BINARY_OP_COMPLEX`
-
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index 89c99ec2f10..0362b8acaca 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -70,6 +70,21 @@ Simple expressions
    Given a numeric type (integer or floating point), build an rvalue for
    the given constant :expr:`long` value.
 
+.. function:: gcc_jit_rvalue *\
+              gcc_jit_context_new_rvalue_from_long_long (gcc_jit_context *ctxt, \
+                                                         gcc_jit_type *numeric_type, \
+                                                         long long value)
+
+   Given a numeric type (integer or floating point), build an rvalue for
+   the given constant :expr:`long long` value.
+
+   This function was added asd in :ref:`LIBGCCJIT_ABI_26`;
+   you can test for its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_LOONG_CONSTANTS
+
 .. function::  gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context *ctxt, \
                                                      gcc_jit_type *numeric_type)
 
@@ -98,6 +113,21 @@ Simple expressions
    Given a numeric type (integer or floating point), build an rvalue for
    the given constant :expr:`double` value.
 
+.. function:: gcc_jit_rvalue *\
+              gcc_jit_context_new_rvalue_from_long_double (gcc_jit_context *ctxt, \
+                                                           gcc_jit_type *numeric_type, \
+                                                           long double value)
+
+   Given a floating point type, build an rvalue for
+   the given constant :expr:`long double`.
+
+   This function was added in :ref:`LIBGCCJIT_ABI_26`;
+   you can test for its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_LOONG_CONSTANTS
+
 .. function:: gcc_jit_rvalue *\
               gcc_jit_context_new_rvalue_from_complex_double (gcc_jit_context *ctxt, \
                                                               gcc_jit_type *numeric_type, \
@@ -114,6 +144,22 @@ Simple expressions
 
       #ifdef LIBGCCJIT_HAVE_COMPLEX
 
+.. function:: gcc_jit_rvalue *\
+              gcc_jit_context_new_rvalue_from_complex_long_double (gcc_jit_context *ctxt,\
+                                                                   gcc_jit_type *numeric_type,\
+                                                                   long double real, long double imag);
+
+   Given a floating point type, build an rvalue for
+   the given constant :expr:`_Complex long double` split into its real and imaginary part. When the result type is
+   non-complex, the imaginary part is discarded.
+
+   This function was added in :ref:`LIBGCCJIT_ABI_26`;
+   you can test for its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_LOONG_CONSTANTS
+
 .. function:: gcc_jit_rvalue *\
               gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, \
                                                    gcc_jit_type *pointer_type, \
@@ -558,7 +604,7 @@ Binary Operation                          C equivalent    Supported operand type
    the imaginary. Negative zeroes are preserved
    and Inf:s do not lead to NaNs.
 
-   This operator  was added in LIBGCCJIT_ABI_26;
+   This operator  was added in :ref:`LIBGCCJIT_ABI_26`;
    you can test for its presence using
 
    .. code-block:: c
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 6c4c8ed5e39..fd60d723bbb 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#include <cstdint>
 #define INCLUDE_MUTEX
 #include "system.h"
 #include "coretypes.h"
@@ -60,6 +61,13 @@ along with GCC; see the file COPYING3.  If not see
 #define SET_DECL_JIT_BIT_FIELD(NODE) \
   (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1)
 
+/* "There are always [atleast] 32 bits in each long, no matter the
+    size of the hosts long.  We handle floating point representations
+    with up to 192 bits", says native_interpret_real() in fold-const.c.
+
+    A define for the amount of these longs needed per long double. */
+#define N_LONGS_LDOUBLE (sizeof (long double) / sizeof (uint32_t) + ((sizeof (long double) % sizeof (uint32_t)) ? 1 : 0))
+
 /* gcc::jit::playback::context::build_cast uses the convert.h API,
    which in turn requires the frontend to provide a "convert"
    function, apparently as a fallback for casts that can be simplified
@@ -937,15 +945,14 @@ new_rvalue_from_const <int> (type *type,
     }
 }
 
-/* Specialization of making an rvalue from a const, for host <long>.  */
+/* Specialization of making an rvalue from a const, for host <long long>. */
 
 template <>
 rvalue *
 context::
-new_rvalue_from_const <long> (type *type,
-			      long value)
+new_rvalue_from_const <long long> (type *type,
+				   long long value)
 {
-  // FIXME: type-checking, or coercion?
   tree inner_type = type->as_tree ();
   if (INTEGRAL_TYPE_P (inner_type))
     {
@@ -980,6 +987,17 @@ new_rvalue_from_const <long> (type *type,
     }
 }
 
+/* Specialization of making an rvalue from a const, for host <long>.  */
+
+template <>
+rvalue *
+context::
+new_rvalue_from_const <long> (type *type,
+			      long value)
+{
+  return new_rvalue_from_const <long long> (type, value);
+}
+
 /* Specialization of making an rvalue from a const, for host <double>.  */
 
 template <>
@@ -1041,6 +1059,65 @@ new_rvalue_from_const <double> (type *type,
     }
 }
 
+/* Specialization of making an rvalue from a const, for host <long double>.  */
+
+template <>
+rvalue *
+context::
+new_rvalue_from_const <long double> (type *type,
+				     long double value)
+{
+  tree inner_type = type->as_tree ();
+
+  scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (long_double_type_node);
+
+  union
+  {
+    long double as_long_double;
+    uint32_t as_uint32s[N_LONGS_LDOUBLE];
+  } u_real, u_imag;
+
+  u_real.as_long_double = value;
+
+  long int as_long_ints[N_LONGS_LDOUBLE];
+
+  for (unsigned i = 0; i < N_LONGS_LDOUBLE; i++)
+    as_long_ints[i] = u_real.as_uint32s[i];
+
+  REAL_VALUE_TYPE real_value;
+  real_from_target (&real_value, as_long_ints, mode);
+
+  if (COMPLEX_FLOAT_TYPE_P (inner_type))
+    {
+      tree tree_real;
+      tree tree_imag;
+      tree real_type;
+
+      REAL_VALUE_TYPE imag_value;
+
+      long int zero_as_long_ints[N_LONGS_LDOUBLE];
+      u_imag.as_long_double = 0.;
+
+      for (unsigned i = 0; i < N_LONGS_LDOUBLE; i++)
+	zero_as_long_ints[i] = u_imag.as_uint32s[i];
+
+      real_from_target (&imag_value, zero_as_long_ints, mode);
+
+      real_type = complex_real_to_real (inner_type);
+
+      tree_real = build_real (real_type, real_value);
+      tree_imag = build_real (real_type, imag_value);
+
+      tree inner = build_complex (inner_type, tree_real, tree_imag);
+      return new rvalue (this, inner);
+    }
+  else
+    {
+      tree inner = build_real (inner_type, real_value);
+      return new rvalue (this, inner);
+    }
+}
+
 /* Specialization of making an rvalue from a const,
    for host complex double. */
 
@@ -1096,6 +1173,65 @@ new_rvalue_from_const <host_pair<double>> (type *type,
     }
 }
 
+/* Specialization of making an rvalue from a const,
+   for host complex long dobule. */
+
+template <>
+rvalue *
+context::
+new_rvalue_from_const <host_pair<long double>> (type *type,
+						host_pair<long double> value)
+{
+  tree inner_type = type->as_tree ();
+
+  scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (long_double_type_node);
+
+  union
+  {
+    long double as_long_double;
+    uint32_t as_uint32s[N_LONGS_LDOUBLE];
+  } u_real, u_imag;
+
+  u_real.as_long_double = value.m_a;
+  long int as_long_ints[N_LONGS_LDOUBLE];
+
+  for (unsigned i = 0; i < N_LONGS_LDOUBLE; i++)
+    as_long_ints[i] = u_real.as_uint32s[i];
+
+  REAL_VALUE_TYPE real_value;
+  real_from_target (&real_value, as_long_ints, mode);
+
+  if (COMPLEX_FLOAT_TYPE_P (inner_type))
+    {
+      tree tree_real;
+      tree tree_imag;
+      tree real_type;
+
+      REAL_VALUE_TYPE imag_value;
+
+      long int value_as_long_ints[N_LONGS_LDOUBLE];
+      u_imag.as_long_double = value.m_b;
+
+      for (unsigned i = 0; i < N_LONGS_LDOUBLE; i++)
+	value_as_long_ints[i] = u_imag.as_uint32s[i];
+
+      real_from_target (&imag_value, value_as_long_ints, mode);
+
+      real_type = complex_real_to_real (inner_type);
+
+      tree_real = build_real (real_type, real_value);
+      tree_imag = build_real (real_type, imag_value);
+
+      tree inner = build_complex (inner_type, tree_real, tree_imag);
+      return new rvalue (this, inner);
+    }
+  else
+    {
+      tree inner = build_real (inner_type, real_value);
+      return new rvalue (this, inner);
+    }
+}
+
 /* Specialization of making an rvalue from a const, for host <void *>.  */
 
 template <>
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index aa11ed5171a..bcb4a4e3a8b 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "pretty-print.h"
 #include "toplev.h"
 
+
 #include <math.h>
 
 #include "jit-builtins.h"
@@ -1836,8 +1837,48 @@ recording::context::dump_reproducer_to_file (const char *path)
 	   " gcc_jit_context_dump_reproducer_to_file.\n\n");
   print_version (r.get_file (), "  ", false);
   r.write ("*/\n");
-  r.write ("#include <libgccjit.h>\n\n");
-  r.write ("#pragma GCC diagnostic ignored \"-Wunused-variable\"\n\n");
+  r.write (
+    "#include <libgccjit.h>\n"
+    "#include <math.h>\n"
+    "#include <complex.h>\n"
+    "#include <string.h>\n\n");
+  r.write ("#pragma GCC diagnostic ignored \"-Wunused-variable\"\n");
+  r.write ("#pragma GCC diagnostic ignored \"-Wunused-function\"\n\n");
+  /* Type punning unions */
+  r.write ("union dull { double d; unsigned long long ull; };\n\n");
+  r.write (
+    "union ldarr { long double ld; unsigned arr[sizeof (long double)];};\n\n");
+
+  /* Functions for type punning nan:s, keeping bit representation */
+  r.write (
+    "/* Convert type punned uint 64 to double NaN.\n"
+    "   Might lose/corrupt payload between architectures. */\n"
+    "static double\n"
+    "ull_to_d (unsigned long long ull)\n"
+    "{\n"
+    "  union dull u; u.ull = ull;\n"
+    "  /* Paranoia check for foreign NaN representation. */\n"
+    "  if (!isnan (u.d)) return NAN;\n"
+    "  return u.d;\n"
+    "}\n\n");
+  r.write (
+    "/* Convert array to long double NaN.\n"
+    "   Might lose/corrupt payload between architectures. */\n"
+    "static long double\n"
+    "arr_to_ld (unsigned char *arr, int len)\n"
+    "{\n"
+    "  union ldarr u;\n"
+    /* Since long double sizes can vary between architectures,
+       we need to handle that. */
+    "  /* For foreign long double sizes */\n"
+    "  if (sizeof u.arr != len) return NAN;\n"
+    "  memcpy (u.arr, arr, len);\n"
+    /* The size might fool us becouse of padding, so check it is a nan. */
+    "  /* Handle foreign representations that is not NaN on this machine. */\n"
+    "  if (!isnan (u.ld)) return NAN;\n"
+    "  return u.ld;\n"
+    "}\n\n");
+
   r.write ("static void\nset_options (");
   r.write_params (contexts);
   r.write (");\n\n");
@@ -5135,11 +5176,12 @@ recording::global::write_reproducer (reproducer &r)
 /* Explicit specialization of the various mementos we're interested in.  */
 template class recording::memento_of_new_rvalue_from_const <int>;
 template class recording::memento_of_new_rvalue_from_const <long>;
+template class recording::memento_of_new_rvalue_from_const <long long>;
 template class recording::memento_of_new_rvalue_from_const <double>;
 template class recording::memento_of_new_rvalue_from_const <long double>;
 template class recording::memento_of_new_rvalue_from_const <host_pair<double>>;
 template class
-recording::memento_of_new_rvalue_from_const <long double[2]>;
+recording::memento_of_new_rvalue_from_const <host_pair<long double>>;
 template class recording::memento_of_new_rvalue_from_const <void *>;
 
 /* Implementation of the pure virtual hook recording::memento::replay_into
@@ -5276,6 +5318,70 @@ recording::memento_of_new_rvalue_from_const <long>::write_reproducer (reproducer
 	   m_value);
 	   }
 
+/* The make_debug_string specialization for <long long>, rendering it as
+     (TARGET_TYPE)LITERAL
+   e.g.
+     "(long long)42". */
+
+template <>
+string *
+memento_of_new_rvalue_from_const <long long>::make_debug_string ()
+{
+  return string::from_printf (m_ctxt,
+			      "(%s)%lli",
+			      m_type->get_debug_string (),
+			      m_value);
+}
+
+/* The get_wide_int specialization for <long long>. */
+
+template <>
+bool
+memento_of_new_rvalue_from_const <long long>::get_wide_int (wide_int *out) const
+{
+  *out = wi::shwi (m_value, sizeof (m_value) * 8);
+  return true;
+}
+
+/* The write_reproducer specialization for <long long>. */
+
+template <>
+void
+recording::memento_of_new_rvalue_from_const <long long>::
+write_reproducer (reproducer &r)
+{
+  const char *id = r.make_identifier (this, "rvalue");
+
+  /* Same special case as in long */
+  if (m_value == LONG_LONG_MIN)
+    {
+      r.write (
+	"  gcc_jit_rvalue *%s =\n"
+	"    gcc_jit_context_new_rvalue_from_long_long (\n"
+	"      %s, /* gcc_jit_context *ctxt */\n"
+	"      %s, /* gcc_jit_type *numeric_type */\n"
+	"      %lldLL - 1); /* long long value */\n",
+	id,
+	r.get_identifier (get_context ()),
+	r.get_identifier_as_type (m_type),
+	m_value + 1);
+      return;
+    }
+
+  r.write (
+    "  gcc_jit_rvalue *%s =\n"
+    "    gcc_jit_context_new_rvalue_from_long_long (\n"
+    "      %s, /* gcc_jit_context *ctxt */\n"
+    "      %s, /* gcc_jit_type *numeric_type */\n"
+    "      %lldLL); /* long long value */\n",
+    id,
+    r.get_identifier (get_context ()),
+    r.get_identifier_as_type (m_type),
+    m_value);
+}
+
+
+
 /* The make_debug_string specialization for <double>, rendering it as
      (TARGET_TYPE)LITERAL
    e.g.
@@ -5286,7 +5392,7 @@ string *
 memento_of_new_rvalue_from_const <double>::make_debug_string ()
 {
   return string::from_printf (m_ctxt,
-			      "(%s)%f",
+			      "(%s)%g",
 			      m_type->get_debug_string (),
 			      m_value);
 }
@@ -5300,6 +5406,18 @@ memento_of_new_rvalue_from_const <double>::get_wide_int (wide_int *) const
   return false;
 }
 
+/* For typepunning NaNs. */
+union dull {
+  double d;
+  unsigned long long ull;
+};
+
+union ldarr {
+  long double ld;
+  unsigned char arr[sizeof(long double)];
+};
+
+
 /* The write_reproducer specialization for <double>.  */
 
 template <>
@@ -5307,14 +5425,154 @@ void
 recording::memento_of_new_rvalue_from_const <double>::write_reproducer (reproducer &r)
 {
   const char *id = r.make_identifier (this, "rvalue");
-  r.write ("  gcc_jit_rvalue *%s =\n"
-    "    gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
-    "                                            %s, /* gcc_jit_type *numeric_type */\n"
-    "                                            %f); /* double value */\n",
-    id,
-    r.get_identifier (get_context ()),
-    r.get_identifier_as_type (m_type),
-    m_value);
+
+  if (std::isfinite (m_value))
+    r.write ("  gcc_jit_rvalue *%s =\n"
+      "    gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
+      "                                            %s, /* gcc_jit_type *numeric_type */\n"
+      "                                            /* %.9g */\n"
+      "                                            %a);\n",
+      id,
+      r.get_identifier (get_context ()),
+      r.get_identifier_as_type (m_type),
+      m_value, m_value);
+   else if (std::isinf (m_value))
+     {
+       const char *sign = "";
+       if (m_value < 0)
+	 sign = "-";
+
+       r.write ("  gcc_jit_rvalue *%s =\n"
+	 "    gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
+	 "                                            %s, /* gcc_jit_type *numeric_type */\n"
+	 "                                            /* inf */\n"
+	 "                                            %sINFINITY);\n",
+	 id,
+	 r.get_identifier (get_context ()),
+	 r.get_identifier_as_type (m_type),
+	 sign);
+      }
+    else if (std::isnan (m_value)) {
+      union dull u;
+      u.d = m_value;
+      r.write ("  gcc_jit_rvalue *%s =\n"
+	"    gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
+	"                                            %s, /* gcc_jit_type *numeric_type */\n"
+	"                                            /* NaN */\n"
+	"                                            ull_to_d(%#llx));\n",
+	id,
+	r.get_identifier (get_context ()),
+	r.get_identifier_as_type (m_type),
+	u.ull);
+
+    }
+}
+
+/* The make_debug_string specialization for <long double>, rendering it as
+     (TARGET_TYPE)LITERAL
+   e.g.
+     "(float)42.0".  */
+
+template <>
+string *
+memento_of_new_rvalue_from_const <long double>::make_debug_string ()
+{
+  return string::from_printf (m_ctxt,
+			      "(%s)%Lg",
+			      m_type->get_debug_string (),
+			      m_value);
+}
+
+/* The get_wide_int specialization for <double>.  */
+
+template <>
+bool
+memento_of_new_rvalue_from_const <long double>::get_wide_int (wide_int *) const
+{
+  return false;
+}
+
+/* Helper function for write_reproducer()
+
+   Write an array of unsigned chars to the reproducer, like:
+   {0x12, 0x34, ... } */
+static void
+reproducer_write_arr (reproducer &r, const unsigned char *arr, size_t len)
+{
+  if (len == 0)
+    return;
+
+  r.write ("{");
+  for (size_t i = 0; i < len - 1; i++)
+    r.write ("%#x , ", arr[i]);
+  r.write ("%#x }", arr[len - 1]);
+}
+
+/* The write_reproducer specialization for <double>.  */
+
+template <>
+void
+recording::memento_of_new_rvalue_from_const <long double>::
+write_reproducer (reproducer &r)
+{
+  const char *id = r.make_identifier (this, "rvalue");
+
+  if (isfinite (m_value))
+    r.write (
+      "  gcc_jit_rvalue *%s =\n"
+      "    gcc_jit_context_new_rvalue_from_long_double (\n"
+      "      %s, /* gcc_jit_context *ctxt */\n"
+      "      %s, /* gcc_jit_type *numeric_type */\n"
+      "      /* %.9Lg */\n"
+      "      %LaL); /* long double value */\n",
+      id,
+      r.get_identifier (get_context ()),
+      r.get_identifier_as_type (m_type),
+      m_value, m_value);
+  else if (isinf (m_value))
+    {
+      const char *sign = "";
+      if (m_value < 0)
+	sign = "-";
+      r.write (
+      "  gcc_jit_rvalue *%s =\n"
+      "    gcc_jit_context_new_rvalue_from_long_double (\n"
+      "      %s, /* gcc_jit_context *ctxt */\n"
+      "      %s, /* gcc_jit_type *numeric_type */\n"
+      "      /* inf */\n"
+      "      %sINFINITY);\n",
+      id,
+      r.get_identifier (get_context ()),
+      r.get_identifier_as_type (m_type),
+      sign);
+    }
+  else
+    {
+      union ldarr u; /* For type punning to array */
+      u.ld = m_value;
+
+      r.write ("  gcc_jit_rvalue *%s;\n", id);
+      /* Scope for local */
+      r.write ("  { /* long double NaN stored in char arr */\n");
+      /* Write an char arr of the bytes of the NaN */
+      r.write ("    unsigned char arr[] = ");
+      reproducer_write_arr (r, u.arr, sizeof u.arr);
+      r.write (";\n");
+
+      r.write (
+      "    %s =\n"
+      "      gcc_jit_context_new_rvalue_from_long_double (\n"
+      "        %s, /* gcc_jit_context *ctxt */\n"
+      "        %s, /* gcc_jit_type *numeric_type */\n"
+      "        /* %Lg */\n"
+      "        arr_to_ld (arr, sizeof arr));\n",
+      id,
+      r.get_identifier (get_context ()),
+      r.get_identifier_as_type (m_type),
+      m_value);
+
+      r.write ("  }\n"); /* Close scope */
+    }
 }
 
 /* The make_debug_string specialization for complex double, rendering it as
@@ -5404,6 +5662,115 @@ write_reproducer (reproducer &r)
   r.write (");\n\n"); /* Close the function call */
 }
 
+template <>
+string *
+memento_of_new_rvalue_from_const <host_pair<long double>>::
+make_debug_string ()
+{
+  long double real = m_value.m_a;
+  long double imag = m_value.m_b;
+  return string::from_printf (m_ctxt,
+			      "(%s)(%Lg%+Lgj)",
+			      m_type->get_debug_string (),
+			      real, imag);
+}
+
+/* The get_wide_int specialization for complex long double.  */
+
+template <>
+bool
+memento_of_new_rvalue_from_const <host_pair<long double>>::
+get_wide_int (wide_int *) const
+{
+  return false;
+}
+
+/* The write_reproducer specialization for complex long double.  */
+
+template <>
+void
+recording::memento_of_new_rvalue_from_const <host_pair<long double>>::
+write_reproducer (reproducer &r)
+{
+  union ldarr ureal, uimag;
+  const char *id = r.make_identifier (this, "rvalue");
+  long double real = m_value.m_a;
+  long double imag = m_value.m_b;
+
+  int has_nan = isnan (real) || isnan (imag);
+
+  if (has_nan)
+    {
+      r.write ("  gcc_jit_rvalue *%s;\n", id);
+      /* Scope for multiple "NaN-arrays" in the source file to not clash */
+      r.write ("  {\n");
+    }
+  if (isnan (real))
+    {
+      /* Write the raw bytes of the long double as an char array
+	 to store it in the source code.
+	 I.e. unsigned char arr[] = {0x1, 0x2, 0x3 ... }; */
+      ureal.ld = real;
+      r.write ("    unsigned char arr_real[] = ");
+      reproducer_write_arr (r, ureal.arr, sizeof ureal.arr);
+      r.write (";\n");
+    }
+  if (isnan (imag))
+    {
+      uimag.ld = imag;
+      r.write ("    unsigned char arr_imag[] = ");
+      reproducer_write_arr (r, uimag.arr, sizeof uimag.arr);
+      r.write (";\n");
+    }
+
+  if (has_nan)
+    r.write ("  "); /* Definition is outside the scope for NaNs */
+  else
+    r.write ("  gcc_jit_rvalue *");
+
+  r.write ("%s =\n"
+    "    gcc_jit_context_new_rvalue_from_complex_long_double (\n"
+    "      %s, /* gcc_jit_context *ctxt */\n"
+    "      %s, /* gcc_jit_type *numeric_type */\n"
+    "      /* %.9Lg + i*%.9Lg */\n"
+    "      ", /* real, imag); */
+    id,
+    r.get_identifier (get_context ()),
+    r.get_identifier_as_type (m_type),
+    real, imag);
+
+  if (isfinite (real))
+    r.write ("%LaL, ", real);
+  else if (isinf (real))
+    {
+      if (real < 0)
+	r.write ("-INFINITY, ");
+      else
+	r.write ("INFINITY, ");
+    }
+  else if (isnan (real))
+    {
+      /* Convert the char array written above, to a long double */
+      r.write ("arr_to_ld (arr_real, sizeof arr_real), ");
+    }
+
+  if (isfinite (imag))
+    r.write ("%LaL", imag);
+  else if (isinf (imag))
+    {
+      if (imag < 0)
+	r.write ("-INFINITY");
+      else
+	r.write ("INFINITY");
+    }
+  else if (isnan (imag))
+    {
+      r.write ("arr_to_ld (arr_imag, sizeof arr_imag)");
+    }
+  r.write(");\n\n"); /* Close function call */
+
+  if (has_nan)
+    r.write ("  }\n"); /* Close NaN-array scope */
 }
 
 /* The make_debug_string specialization for <void *>, rendering it as
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index b965d99d3f8..5a76b9d7648 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -188,6 +188,10 @@ namespace gccjit
 		       int value) const;
     rvalue new_rvalue (type numeric_type,
 		       long value) const;
+#ifdef LIBGCCJIT_INCLUDE_LONGLONGS
+    rvalue new_rvalue (type numeric_type,
+		       long long value) const;
+#endif
     rvalue zero (type numeric_type) const;
     rvalue one (type numeric_type) const;
     rvalue new_rvalue (type numeric_type,
@@ -956,6 +960,19 @@ context::new_rvalue (type numeric_type,
 					  value));
 }
 
+#ifdef LIBGCCJIT_INCLUDE_LONGLONGS
+inline rvalue
+context::new_rvalue (type numeric_type,
+		     long long value) const
+{
+  return rvalue (
+    gcc_jit_context_new_rvalue_from_long_long (
+      m_inner_ctxt,
+      numeric_type.get_inner_type (),
+      value));
+}
+#endif
+
 inline rvalue
 context::zero (type numeric_type) const
 {
@@ -1002,6 +1019,17 @@ context::new_rvalue (type numeric_type,
       real, imag));
 }
 
+inline rvalue
+context::new_rvalue (type numeric_type,
+		     long double real, long double imag) const
+{
+  return rvalue (
+    gcc_jit_context_new_rvalue_from_complex_long_double (
+      m_inner_ctxt,
+      numeric_type.get_inner_type (),
+      real, imag));
+}
+
 inline rvalue
 context::new_rvalue (type pointer_type,
 		     void *value) const
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 79a213624da..21d0e0ac3d4 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -1982,6 +1982,19 @@ gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
 	  ->new_rvalue_from_const <long> (numeric_type, value));
 }
 
+gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_long_long (gcc_jit_context *ctxt,
+					   gcc_jit_type *numeric_type,
+					   long long value)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
+
+  return ((gcc_jit_rvalue *)ctxt
+	  ->new_rvalue_from_const <long long> (numeric_type, value));
+}
+
 /* Public entrypoint.  See description in libgccjit.h.
 
    This is essentially equivalent to:
@@ -2035,6 +2048,19 @@ gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
 	  ->new_rvalue_from_const <double> (numeric_type, value));
 }
 
+gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_long_double (gcc_jit_context *ctxt,
+					     gcc_jit_type *numeric_type,
+					     long double value)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
+
+  return ((gcc_jit_rvalue *)ctxt
+	  ->new_rvalue_from_const <long double> (numeric_type, value));
+}
+
 gcc_jit_rvalue *
 gcc_jit_context_new_rvalue_from_complex_double (gcc_jit_context *ctxt,
 						gcc_jit_type *numeric_type,
@@ -2056,6 +2082,28 @@ gcc_jit_context_new_rvalue_from_complex_double (gcc_jit_context *ctxt,
 	      numeric_type, gcc::jit::host_pair<double> (real, imag)));
 }
 
+gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_complex_long_double (
+  gcc_jit_context *ctxt,
+  gcc_jit_type *numeric_type,
+  long double real,
+  long double imag)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  JIT_LOG_FUNC (ctxt->get_logger ());
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
+
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    numeric_type->is_float (),
+    ctxt, NULL,
+    "not a floating point type (type: %s)",
+    numeric_type->get_debug_string ());
+
+  return ((gcc_jit_rvalue *)ctxt->
+	  new_rvalue_from_const <gcc::jit::host_pair<long double>> (
+	    numeric_type, gcc::jit::host_pair<long double> (real, imag)));
+}
+
 
 /* Public entrypoint.  See description in libgccjit.h.
 
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 6ca3cd90b57..8388e9d4a0f 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -1084,6 +1084,20 @@ gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
 				      gcc_jit_type *numeric_type,
 				      long value);
 
+#define LIBGCCJIT_HAVE_LOONG_CONSTANTS
+/* Get a constant from a long long.
+
+   This function was added in LIBGCCJIT_ABI_26. You can test for
+   its presence with:
+     #ifdef LIBGCCJIT_HAVE_LOONG_CONSTANTS */
+
+#ifdef LIBGCCJIT_INCLUDE_LONGLONGS
+extern gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_long_long (gcc_jit_context *ctxt,
+					   gcc_jit_type *numeric_type,
+					   long long value);
+#endif
+
 extern gcc_jit_rvalue *
 gcc_jit_context_zero (gcc_jit_context *ctxt,
 		      gcc_jit_type *numeric_type);
@@ -1098,7 +1112,17 @@ gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
 					gcc_jit_type *numeric_type,
 					double value);
 
-/* Complex floating-point constants.
+/* Get a constant from a long double.
+
+   This function was added in LIBGCCJIT_ABI_26. You can test for
+   its presence with:
+     #ifdef LIBGCCJIT_HAVE_LOONG_CONSTANTS */
+extern gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_long_double (gcc_jit_context *ctxt,
+					     gcc_jit_type *numeric_type,
+					     long double value);
+
+/* Get a constant from a complex double.
 
    This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
    presence using
@@ -1110,6 +1134,18 @@ gcc_jit_context_new_rvalue_from_complex_double (gcc_jit_context *ctxt,
 						double real,
 						double imag);
 
+/* Get a constant from a complex long double.
+
+   This API entrypoint was added in LIBGCCJIT_ABI_26; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_LOONG_CONSTANTS */
+
+extern gcc_jit_rvalue *
+gcc_jit_context_new_rvalue_from_complex_long_double (
+  gcc_jit_context *ctxt,
+  gcc_jit_type *numeric_type,
+  long double real, long double imag);
+
 /* Pointers.  */
 extern gcc_jit_rvalue *
 gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index efa80d9cf2f..aba2d69079f 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -280,5 +280,9 @@ LIBGCCJIT_ABI_25 {
 LIBGCCJIT_ABI_26 {
   global:
     gcc_jit_context_new_rvalue_from_complex_double;
+    gcc_jit_context_new_rvalue_from_complex_long_double;
+    gcc_jit_context_new_rvalue_from_long_double;
+    gcc_jit_context_new_rvalue_from_long_long;
     gcc_jit_context_set_bool_enable_complex_types;
 } LIBGCCJIT_ABI_25;
+
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index b8693bd5b9c..3880b428c26 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -277,6 +277,13 @@
 #undef create_code
 #undef verify_code
 
+/* test-long-literals.c */
+#define create_code create_code_long_literals
+#define verify_code verify_code_long_literals
+#include "test-long-literals.c"
+#undef create_code
+#undef verify_code
+
 /* test-long-string-literal.c */
 #define create_code create_code_long_string_literal
 #define verify_code verify_code_long_string_literal
diff --git a/gcc/testsuite/jit.dg/test-long-literals.c b/gcc/testsuite/jit.dg/test-long-literals.c
new file mode 100644
index 00000000000..22c6c85a28c
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-long-literals.c
@@ -0,0 +1,274 @@
+/* Test long literals.
+
+   I.e. long long, long double and long complex doubles.
+
+   Also test NaN:s and inf:s with double. */
+
+
+#include <complex.h>
+#include <limits.h>
+#include <math.h>
+#include <string.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+int compare_nans(double d1, double d2)
+{
+  union {double d; unsigned long long ull;} u1, u2;
+
+  u1.d = d1;
+  u2.d = d2;
+
+  return u1.ull == u2.ull;
+}
+
+static void
+make_code_lit_cld(gcc_jit_context *ctxt,
+                  const char *fn_name,
+                  int type,
+                  _Complex long double local_val,
+                  int lit_type)
+{
+  gcc_jit_type *tt = gcc_jit_context_get_type (ctxt, type);
+
+  gcc_jit_function *foo = gcc_jit_context_new_function (ctxt, 0,
+    GCC_JIT_FUNCTION_EXPORTED,
+    tt, fn_name, 0, 0, 0);
+
+  gcc_jit_block *block = gcc_jit_function_new_block (foo, "start");
+
+  /* local_type f1 = local_val; */
+  gcc_jit_lvalue *f1 = gcc_jit_function_new_local (foo, 0, tt, "f1");
+
+  gcc_jit_rvalue *r1;
+
+  if (lit_type == 'L')
+    r1 = gcc_jit_context_new_rvalue_from_long_double (
+      ctxt, tt, creall(local_val));
+  else if (lit_type == 'C')
+    r1 = gcc_jit_context_new_rvalue_from_complex_long_double (
+           ctxt, tt, creall (local_val), cimagl(local_val));
+
+  gcc_jit_block_add_assignment (block, 0, f1, r1);
+
+  gcc_jit_block_end_with_return (block, 0, gcc_jit_lvalue_as_rvalue(f1));
+}
+
+static void
+make_code_lit_d (gcc_jit_context *ctxt,
+                 const char *fn_name,
+                 int type,
+                 _Complex double local_val,
+                 int lit_type)
+{
+  gcc_jit_type *tt = gcc_jit_context_get_type (ctxt, type);
+
+  gcc_jit_function *foo = gcc_jit_context_new_function (ctxt, 0,
+    GCC_JIT_FUNCTION_EXPORTED,
+    tt, fn_name, 0, 0, 0);
+
+  gcc_jit_block *block = gcc_jit_function_new_block (foo, "start");
+
+  /* local_type f1 = local_val; */
+  gcc_jit_lvalue *f1 = gcc_jit_function_new_local (foo, 0, tt, "f1");
+
+  gcc_jit_rvalue *r1;
+
+  if (lit_type == 'd')
+    r1 = gcc_jit_context_new_rvalue_from_double (
+      ctxt, tt, local_val);
+  else if (lit_type == 'c')
+    r1 = gcc_jit_context_new_rvalue_from_complex_double (
+	   ctxt, tt, creal (local_val), cimag (local_val));
+
+  gcc_jit_block_add_assignment (block, 0, f1, r1);
+
+  gcc_jit_block_end_with_return (block, 0, gcc_jit_lvalue_as_rvalue(f1));
+}
+
+static void
+make_code_lit_ll (gcc_jit_context *ctxt,
+                  const char *fn_name,
+                  int type,
+                  long long local_val)
+{
+  gcc_jit_type *tt = gcc_jit_context_get_type (ctxt, type);
+
+  gcc_jit_function *foo = gcc_jit_context_new_function (ctxt, 0,
+    GCC_JIT_FUNCTION_EXPORTED,
+    tt, fn_name, 0, 0, 0);
+
+  gcc_jit_block *block = gcc_jit_function_new_block (foo, "start");
+
+  /* local_type f1 = local_val; */
+  gcc_jit_lvalue *f1 = gcc_jit_function_new_local (foo, 0, tt, "f1");
+
+  gcc_jit_rvalue *r1;
+
+  r1 = gcc_jit_context_new_rvalue_from_long_long (
+    ctxt, tt, creall(local_val));
+
+  gcc_jit_block_add_assignment (block, 0, f1, r1);
+
+  gcc_jit_block_end_with_return (block, 0, gcc_jit_lvalue_as_rvalue(f1));
+}
+
+
+union uu { double d; long long l; } u;
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  (void) user_data;
+
+  gcc_jit_context_set_bool_enable_complex_types (ctxt, 1);
+
+  make_code_lit_cld (ctxt, "long_double_ldlit_1c1",
+    GCC_JIT_TYPE_LONG_DOUBLE,
+    -1.1L, 'L');
+  make_code_lit_cld (ctxt, "long_double_ldlit_1Ldiv3L",
+    GCC_JIT_TYPE_LONG_DOUBLE,
+    1/3.L, 'L');
+  make_code_lit_cld (ctxt, "long_double_ldlit_inf",
+    GCC_JIT_TYPE_LONG_DOUBLE,
+    INFINITY, 'L');
+  make_code_lit_cld (ctxt, "long_double_ldlit_minf",
+    GCC_JIT_TYPE_LONG_DOUBLE,
+    -INFINITY, 'L');
+  make_code_lit_cld (ctxt, "long_double_ldlit_nan1",
+    GCC_JIT_TYPE_LONG_DOUBLE,
+    nanl("1"), 'L');
+
+  make_code_lit_cld (ctxt, "complex_long_double_cldlit_1div3_2div3j",
+    GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE,
+    1/3.L + 2.Lj/3, 'C');
+
+  make_code_lit_cld (ctxt, "complex_long_double_cldlit_inf_infj",
+    GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE,
+    CMPLXL (INFINITY, INFINITY), 'C');
+  make_code_lit_cld (ctxt, "complex_long_double_cldlit_minf_minfj",
+    GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE,
+    CMPLXL (-INFINITY, -INFINITY), 'C');
+  make_code_lit_cld (ctxt, "complex_long_double_cldlit_nan1_nan2j",
+    GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE,
+    CMPLXL (nanl ("1"), nanl ("2")), 'C');
+
+  make_code_lit_ll (ctxt, "long_long_lllit_2",
+    GCC_JIT_TYPE_LONG_LONG,
+    2);
+
+  make_code_lit_ll (ctxt, "long_long_lllit_min",
+    GCC_JIT_TYPE_LONG_LONG,
+    LLONG_MIN);
+
+  make_code_lit_ll (ctxt, "long_long_lllit_max",
+    GCC_JIT_TYPE_LONG_LONG,
+    LLONG_MAX);
+
+  make_code_lit_ll (ctxt, "ulong_long_lllit_max",
+    GCC_JIT_TYPE_UNSIGNED_LONG_LONG,
+    ULLONG_MAX);
+
+  make_code_lit_d (ctxt, "double_nan1",
+    GCC_JIT_TYPE_DOUBLE,
+    nan("1"), 'd');
+  make_code_lit_d (ctxt, "double_inf",
+    GCC_JIT_TYPE_DOUBLE,
+    INFINITY, 'd');
+  make_code_lit_d (ctxt, "double_minf",
+    GCC_JIT_TYPE_DOUBLE,
+    -INFINITY, 'd');
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  CHECK_NON_NULL (result);
+  {
+    double (*f)() = gcc_jit_result_get_code (
+      result, "double_nan1");
+
+    /* Compare payload of nans. */
+    CHECK(compare_nans (f(), nan("1")));
+  }
+  {
+    double (*f)() = gcc_jit_result_get_code (
+      result, "double_inf");
+
+    CHECK_VALUE (f(), INFINITY);
+  }
+  {
+    double (*f)() = gcc_jit_result_get_code (
+      result, "double_minf");
+
+    CHECK_VALUE (f(), -INFINITY);
+  }
+  {
+    long double (*f)() = gcc_jit_result_get_code (
+      result, "long_double_ldlit_1c1");
+
+    CHECK_VALUE(f (), -1.1L);
+  }
+  {
+    long double (*f)() = gcc_jit_result_get_code (
+      result, "long_double_ldlit_1Ldiv3L");
+
+    CHECK_VALUE(f (), 1.L/3.L);
+  }
+  {
+    _Complex long double (*f)() = gcc_jit_result_get_code (
+      result, "complex_long_double_cldlit_1div3_2div3j");
+
+    CHECK_VALUE (f(), 1/3.L + 2.Lj/3);
+  }
+  {
+    _Complex long double (*f)() = gcc_jit_result_get_code (
+      result, "complex_long_double_cldlit_inf_infj");
+
+    CHECK_VALUE (f(),CMPLXL (INFINITY, INFINITY));
+  }
+  {
+    _Complex long double (*f)() = gcc_jit_result_get_code (
+      result, "complex_long_double_cldlit_minf_minfj");
+
+    CHECK_VALUE (f(),CMPLXL (-INFINITY, -INFINITY));
+  }
+  {
+    _Complex long double (*f)() = gcc_jit_result_get_code (
+      result, "complex_long_double_cldlit_nan1_nan2j");
+
+    _Complex long double ans = f ();
+
+    /* There are some issues with padding bytes trying to
+       do a bytewise compare so just check they are nans for
+       compatibility between different platforms. I.e. don't
+       verify the nan payload is the same. */
+    CHECK (isnan (creall (ans)));
+    CHECK (isnan (cimagl (ans)));
+  }
+  {
+    long long (*f)() = gcc_jit_result_get_code (
+      result, "long_long_lllit_2");
+
+    CHECK_VALUE (f(), 2);
+  }
+  {
+    long long (*f)() = gcc_jit_result_get_code (
+      result, "long_long_lllit_min");
+
+    CHECK_VALUE (f(), LLONG_MIN);
+  }
+  {
+    long long (*f)() = gcc_jit_result_get_code (
+      result, "long_long_lllit_max");
+
+    CHECK_VALUE (f(), LLONG_MAX);
+  }
+  {
+    unsigned long long (*f)() = gcc_jit_result_get_code (
+      result, "ulong_long_lllit_max");
+
+    CHECK_VALUE (f(), ULLONG_MAX);
+  }
+}
-- 
2.42.0


  reply	other threads:[~2023-11-26 23:15 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-20 22:02 [PATCH 0/2] " Petter Tomner
2023-11-20 22:10 ` [PATCH 1/2] " Petter Tomner
2023-11-21 14:43   ` David Malcolm
2023-11-26 23:15     ` Petter Tomner
2023-11-20 22:15 ` [PATCH 2/2] " Petter Tomner
2023-11-21 15:56   ` David Malcolm
2023-11-26 23:15     ` Petter Tomner [this message]
2023-12-11 23:35       ` Petter Tomner
  -- strict thread matches above, loose matches on Subject: below --
2021-10-21 13:02 [PATCH 0/2] " Petter Tomner
2021-10-21 13:13 ` [PATCH 2/2] " Petter Tomner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e7594ba2-6e21-4b6d-a568-cc2d4b2d4d3c@bahnhof.se \
    --to=tomner@bahnhof.se \
    --cc=dmalcolm@redhat.com \
    --cc=jit@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).