public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
From: Antoni Boucher <bouanto@zoho.com>
To: David Malcolm <dmalcolm@redhat.com>, Jakub Jelinek <jakub@redhat.com>
Cc: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] libgccjit: Add support for sized integer types, including 128-bit integers [PR95325]
Date: Fri, 08 Apr 2022 16:29:56 -0400	[thread overview]
Message-ID: <634faf0f0f7aab414fd2764b8bb794b4144a4a0b.camel@zoho.com> (raw)
In-Reply-To: <70459fd53eb780e3c3735955539a1bb7a1024bf4.camel@zoho.com>

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

David, it seems you missed this email that contains the updated patch
and a few questions.

Attaching the patch again.

Thanks for the reviews!

On Fri, 2022-01-21 at 11:22 -0500, Antoni Boucher via Jit wrote:
> David: this is the email I was talking about in my other email.
> Here's the updated patch.
> 
> By the way, I find the usage of NUM_GCC_JIT_TYPES brittle. Would it
> be
> better to switch to a new enum value for that instead?
> 
> See comments below.
> 
> Le jeudi 20 mai 2021 à 15:25 -0400, David Malcolm a écrit :
> > On Tue, 2021-05-18 at 14:53 +0200, Jakub Jelinek via Jit wrote:
> > > On Tue, May 18, 2021 at 08:23:56AM -0400, Antoni Boucher via Gcc-
> > > patches wrote:
> > > > Hello.
> > > > This patch add support for sized integer types.
> > > > Maybe it should check whether the size of a byte for the
> > > > current
> > > > platform is 8 bits and do other checks so that they're only
> > > > available
> > > > when it makes sense.
> > > > What do you think?
> > > 
> > > Not a review, just a comment.  The 128-bit integral types are
> > > available
> > > only on some targets, the test e.g. the C/C++ FE do for those is
> > > targetm.scalar_mode_supported_p (TImode)
> > > and so even libgccjit shouldn't provide those types
> > > unconditionally.
> > > Similarly for the tests (though it could be guarded with e.g
> > > #ifdef __SIZEOF_INT128__
> > > in that case).
> > > Also, while currently all in tree targets have BITS_PER_UNIT 8
> > > and
> > > therefore QImode is 8-bit, HImode 16-bit, SImode 32-bit and
> > > DImode
> > > 64-
> > > bit,
> > > in the past and maybe in he future there can be targets that
> > > could
> > > have
> > > e.g. 16-bit or 32-bit QImode and then there wouldn't be any
> > > uint8_t/int8_t
> > > and int16_t would be intQImode_type_node etc.
> > >   uint16_type_node = make_or_reuse_type (16, 1);
> > >   uint32_type_node = make_or_reuse_type (32, 1);
> > >   uint64_type_node = make_or_reuse_type (64, 1);
> > >   if (targetm.scalar_mode_supported_p (TImode))
> > >     uint128_type_node = make_or_reuse_type (128, 1);
> > > are always with the given precisions, perhaps jit should use
> > > signed_type_for (uint16_type_node) etc.?
> > 
> > I seem to have mislaid Antoni's original email (sorry), so I'll
> > reply
> > to Jakub's.
> > 
> > > 2021-05-18  Antoni Boucher  <bouanto@zoho.com>
> > > 
> > >     gcc/jit/
> > >             PR target/95325
> > >             * jit-playback.c: Add support for the sized integer
> > > types.
> > >             * jit-recording.c: Add support for the sized integer
> > > types.
> > >             * libgccjit.h (GCC_JIT_TYPE_UINT8_T,
> > > GCC_JIT_TYPE_UINT16_T,
> > >             GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
> > >             GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T,
> > > GCC_JIT_TYPE_INT16_T,
> > >             GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T,
> > > GCC_JIT_TYPE_INT128_T):
> > >             New enum variants for gcc_jit_types.
> > >     gcc/testsuite/
> > >             PR target/95325
> > >             * jit.dg/test-types.c: Add tests for sized integer
> > > types.
> > 
> > First a high-level question, why not use (or extend)
> > gcc_jit_context_get_int_type instead?
> 
> If I remember correctly, I believe I had some issues with this
> function, like having it return sometimes long long, and other times
> long for the same size. Maybe that was an issue with a global
> variable
> not cleaned up.
> 
> > 
> > Do we really need to extend enum gcc_jit_types?  Is this a quality-
> > of-
> > life thing for users of the library?
> > 
> > That said, recording::context::get_int_type is currently a bit of a
> > hack, and maybe could probably be improved by using the new enum
> > values
> > the patch adds.
> > 
> > IIRC, libgccjit.c does type-checking by comparing recording::type
> > pointer values; does this patch gives us multiple equivalent types
> > that
> > ought to compare as equal?
> > 
> > If a user gets a type via GCC_JIT_TYPE_INT and gets "another" type
> > via
> > GCC_JIT_TYPE_INT32_T and they happen to be the same on the current
> > target, should libgccjit complain if you use "int" when you meant
> > "int32_t", or accept it?
> 
> I updated the function compatible_types to make them compare as
> equal.
> I believe that it's not used everywhere though, so a cast will be
> necessary in some cases.
> 
> > 
> > Various comments inline below...
> > 
> > > diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
> > > index c6136301243..40630aa1ab8 100644
> > > --- a/gcc/jit/jit-playback.c
> > > +++ b/gcc/jit/jit-playback.c
> > > @@ -193,6 +193,27 @@ get_tree_node_for_type (enum gcc_jit_types
> > > type_)
> > >      case GCC_JIT_TYPE_UNSIGNED_INT:
> > >        return unsigned_type_node;
> > >  
> > > +    case GCC_JIT_TYPE_UINT8_T:
> > > +      return unsigned_intQI_type_node;
> > > +    case GCC_JIT_TYPE_UINT16_T:
> > > +      return uint16_type_node;
> > > +    case GCC_JIT_TYPE_UINT32_T:
> > > +      return uint32_type_node;
> > > +    case GCC_JIT_TYPE_UINT64_T:
> > > +      return uint64_type_node;
> > > +    case GCC_JIT_TYPE_UINT128_T:
> > > +      return uint128_type_node;
> > > +    case GCC_JIT_TYPE_INT8_T:
> > > +      return intQI_type_node;
> > > +    case GCC_JIT_TYPE_INT16_T:
> > > +      return intHI_type_node;
> > > +    case GCC_JIT_TYPE_INT32_T:
> > > +      return intSI_type_node;
> > > +    case GCC_JIT_TYPE_INT64_T:
> > > +      return intDI_type_node;
> > > +    case GCC_JIT_TYPE_INT128_T:
> > > +      return intTI_type_node;
> > > +
> > 
> > Jakub has already commented that 128 bit types might not be
> > available.
> > 
> > Ideally we'd report that they're not available as soon as the user
> > tries to use them, in gcc_jit_context_get_type, but unfortunately
> > it
> > looks like the test requires us to use
> > targetm.scalar_mode_supported_p,
> > and that requires us to hold the jit mutex and thus be at playback
> > time.
> > 
> > So I think get_tree_node_for_type should take a context, and add an
> > error on the context if there's a failure, returning NULL. 
> > playback::context::get_type is the only caller currently and has
> > handling for an unrecognized value, so I think that logic needs to
> > be
> > moved to get_tree_node_for_type so that the user can distinguish
> > between unrecognized types versus types that are unsupported on
> > this
> > target.
> > 
> > 
> > > diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
> > > index 117ff70114c..b67ae8bfb78 100644
> > > --- a/gcc/jit/jit-recording.c
> > > +++ b/gcc/jit/jit-recording.c
> > > @@ -2247,6 +2247,18 @@ recording::memento_of_get_type::get_size
> > > ()
> > >      case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
> > >        size = LONG_LONG_TYPE_SIZE;
> > >        break;
> > > +    case GCC_JIT_TYPE_UINT8_T:
> > > +    case GCC_JIT_TYPE_UINT16_T:
> > > +    case GCC_JIT_TYPE_UINT32_T:
> > > +    case GCC_JIT_TYPE_UINT64_T:
> > > +    case GCC_JIT_TYPE_UINT128_T:
> > > +    case GCC_JIT_TYPE_INT8_T:
> > > +    case GCC_JIT_TYPE_INT16_T:
> > > +    case GCC_JIT_TYPE_INT32_T:
> > > +    case GCC_JIT_TYPE_INT64_T:
> > > +    case GCC_JIT_TYPE_INT128_T:
> > > +      size = 128;
> > > +      break;
> > 
> > This gives 128 bits as the size for all of these types, which seems
> > wrong.
> > 
> > >      case GCC_JIT_TYPE_FLOAT:
> > >        size = FLOAT_TYPE_SIZE;
> > >        break;
> > >      case GCC_JIT_TYPE_FLOAT:
> > 
> > > diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
> > > index 5c722c2c57f..5d88033a2ab 100644
> > > --- a/gcc/jit/libgccjit.h
> > > +++ b/gcc/jit/libgccjit.h
> > > @@ -548,6 +548,17 @@ enum gcc_jit_types
> > >    GCC_JIT_TYPE_LONG_LONG, /* signed */
> > >    GCC_JIT_TYPE_UNSIGNED_LONG_LONG,
> > >  
> > > +  GCC_JIT_TYPE_UINT8_T,
> > > +  GCC_JIT_TYPE_UINT16_T,
> > > +  GCC_JIT_TYPE_UINT32_T,
> > > +  GCC_JIT_TYPE_UINT64_T,
> > > +  GCC_JIT_TYPE_UINT128_T,
> > > +  GCC_JIT_TYPE_INT8_T,
> > > +  GCC_JIT_TYPE_INT16_T,
> > > +  GCC_JIT_TYPE_INT32_T,
> > > +  GCC_JIT_TYPE_INT64_T,
> > > +  GCC_JIT_TYPE_INT128_T,
> > > +
> > >    /* Floating-point types  */
> > >  
> > >    GCC_JIT_TYPE_FLOAT,
> > 
> > The patch adds the new enum values between existing values of enum
> > gcc_jit_types, effectively changing the ABI, since e.g. the
> > numerical
> > value of GCC_JIT_TYPE_FLOAT changes with this, and there's no way
> > of
> > telling which enum values a binary linked against libgccjit.so is
> > going
> > to supply when it calls into libgccjit.
> > 
> > If we're going to extend the enum, the new values need to be added
> > to
> > the end, extending the ABI rather than changing it.
> 
> Fixed.
> 
> > 
> > I don't think the patch provides a way to detect that the client
> > code
> > is using the new ABI and thus mark it in the metadata.  I'm not
> > sure
> > how to do that.
> 
> Now this patch adds new functions. Does that solve this issue?
> 
> > 
> > > diff --git a/gcc/testsuite/jit.dg/test-types.c
> > > b/gcc/testsuite/jit.dg/test-types.c
> > > index 8debcd7eb82..9c66284f193 100644
> > > --- a/gcc/testsuite/jit.dg/test-types.c
> > > +++ b/gcc/testsuite/jit.dg/test-types.c
> > 
> > [...snip...]
> > 
> > The tests seem reasonable, but as noted by Jakub the 128-bit
> > support
> > needs to be conditionalized.
> > 
> > Hope this is constructive
> > Dave
> > 
> 


[-- Attachment #2: 0001-libgccjit-Add-support-for-sized-integer-types-includ.patch --]
[-- Type: text/x-patch, Size: 31099 bytes --]

From db8836d1e16e432b6f40a26549648f6477d491bc Mon Sep 17 00:00:00 2001
From: Antoni Boucher <bouanto@zoho.com>
Date: Mon, 10 May 2021 19:43:02 -0400
Subject: [PATCH] libgccjit: Add support for sized integer types, including
 128-bit integers [PR95325]

2022-01-19  Antoni Boucher  <bouanto@zoho.com>

gcc/jit/
	PR target/95325
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_20): New ABI tag.
	* docs/topics/types.rst: Add documentation for the new types
	GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
	GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
	GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T,
	GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T and
	new functions (gcc_jit_compatible_types, gcc_jit_type_get_size).
	* jit-builtins.cc: Add support for BT_UINT128.
	* jit-common.h: Update the value of NUM_GCC_JIT_TYPES.
	* jit-playback.cc: Add support for the sized integer types.
	* jit-recording.cc: Add support for the sized integer types.
	* jit-recording.h: Add support for comparing integer types
	and new function (is_signed).
	* libgccjit.cc: Rename compatible_types to
	gcc_jit_compatible_types and new function (gcc_jit_type_get_size).
	* libgccjit.h: New enum variants for gcc_jit_types
	(GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
	GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
	GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T,
	GCC_JIT_TYPE_INT16_T, GCC_JIT_TYPE_INT32_T,
	GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T) and new functions
	(gcc_jit_compatible_types, gcc_jit_type_get_size).
	libgccjit.map (LIBGCCJIT_ABI_20): New ABI tag.

gcc/testsuite/
	PR target/95325
	* jit.dg/test-types.c: Add tests for sized integer types.
---
 gcc/jit/docs/topics/compatibility.rst |  20 ++++
 gcc/jit/docs/topics/types.rst         |  41 ++++++++
 gcc/jit/jit-builtins.cc               |   1 +
 gcc/jit/jit-common.h                  |   2 +-
 gcc/jit/jit-playback.cc               |  37 ++++++-
 gcc/jit/jit-recording.cc              | 146 +++++++++++++++++++++++++-
 gcc/jit/jit-recording.h               |  16 +++
 gcc/jit/libgccjit.cc                  |  52 +++++----
 gcc/jit/libgccjit.h                   |  32 +++++-
 gcc/jit/libgccjit.map                 |   6 ++
 gcc/testsuite/jit.dg/test-types.c     | 131 +++++++++++++++++++++++
 11 files changed, 457 insertions(+), 27 deletions(-)

diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 16cebe31a10..73a17664698 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -302,3 +302,23 @@ thread-local storage model of a variable:
 section of a variable:
 
   * :func:`gcc_jit_lvalue_set_link_section`
+
+.. _LIBGCCJIT_ABI_20:
+
+``LIBGCCJIT_ABI_20``
+-----------------------
+``LIBGCCJIT_ABI_20`` covers the addition of sized integer types, including
+128-bit integers and helper functions for types:
+
+  * :func:`gcc_jit_compatible_types`
+  * :func:`gcc_jit_type_get_size`
+  * :c:macro:`GCC_JIT_TYPE_UINT8_T`
+  * :c:macro:`GCC_JIT_TYPE_UINT16_T`
+  * :c:macro:`GCC_JIT_TYPE_UINT32_T`
+  * :c:macro:`GCC_JIT_TYPE_UINT64_T`
+  * :c:macro:`GCC_JIT_TYPE_UINT128_T`
+  * :c:macro:`GCC_JIT_TYPE_INT8_T`
+  * :c:macro:`GCC_JIT_TYPE_INT16_T`
+  * :c:macro:`GCC_JIT_TYPE_INT32_T`
+  * :c:macro:`GCC_JIT_TYPE_INT64_T`
+  * :c:macro:`GCC_JIT_TYPE_INT128_T`
diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
index 9779ad26b6f..ededf49e149 100644
--- a/gcc/jit/docs/topics/types.rst
+++ b/gcc/jit/docs/topics/types.rst
@@ -76,6 +76,16 @@ Standard types
    :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG`        C's ``unsigned long``
    :c:data:`GCC_JIT_TYPE_LONG_LONG`            C99's ``long long`` (signed)
    :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG_LONG`   C99's ``unsigned long long``
+   :c:data:`GCC_JIT_TYPE_UINT8_T`              C99's ``uint8_t``
+   :c:data:`GCC_JIT_TYPE_UINT16_T`             C99's ``uint16_t``
+   :c:data:`GCC_JIT_TYPE_UINT32_T`             C99's ``uint32_t``
+   :c:data:`GCC_JIT_TYPE_UINT64_T`             C99's ``uint64_t``
+   :c:data:`GCC_JIT_TYPE_UINT128_T`            C99's ``__uint128_t``
+   :c:data:`GCC_JIT_TYPE_INT8_T`               C99's ``int8_t``
+   :c:data:`GCC_JIT_TYPE_INT16_T`              C99's ``int16_t``
+   :c:data:`GCC_JIT_TYPE_INT32_T`              C99's ``int32_t``
+   :c:data:`GCC_JIT_TYPE_INT64_T`              C99's ``int64_t``
+   :c:data:`GCC_JIT_TYPE_INT128_T`             C99's ``__int128_t``
    :c:data:`GCC_JIT_TYPE_FLOAT`
    :c:data:`GCC_JIT_TYPE_DOUBLE`
    :c:data:`GCC_JIT_TYPE_LONG_DOUBLE`
@@ -467,3 +477,34 @@ Reflection API
       #ifdef LIBGCCJIT_HAVE_REFLECTION
 
    .. type:: gcc_jit_case
+
+.. function::  int\
+               gcc_jit_compatible_types (gcc_jit_type *ltype,
+                                         gcc_jit_type *rtype)
+
+     Return non-zero if the two types are compatible. For instance,
+     if :c:data:`GCC_JIT_TYPE_UINT64_T` and :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG`
+     are the same size on the target, this will return non-zero.
+     The parameters ``ltype`` and ``rtype`` must be non-NULL.
+     Return 0 on errors.
+
+   This entrypoint was added in :ref:`LIBGCCJIT_ABI_20`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS
+
+.. function::  ssize_t\
+               gcc_jit_type_get_size (gcc_jit_type *type)
+
+     Return the size of a type, in bytes. It only works on integer types for now.
+     The parameter ``type`` must be non-NULL.
+     Return -1 on errors.
+
+   This entrypoint was added in :ref:`LIBGCCJIT_ABI_20`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS
diff --git a/gcc/jit/jit-builtins.cc b/gcc/jit/jit-builtins.cc
index 71c38eb0948..b949b734332 100644
--- a/gcc/jit/jit-builtins.cc
+++ b/gcc/jit/jit-builtins.cc
@@ -483,6 +483,7 @@ builtins_manager::make_primitive_type (enum jit_builtin_type type_id)
     case BT_UINT16: return m_ctxt->get_int_type (2, false);
     case BT_UINT32: return m_ctxt->get_int_type (4, false);
     case BT_UINT64: return m_ctxt->get_int_type (8, false);
+    case BT_UINT128: return m_ctxt->get_int_type (16, false);
     // case BT_WORD:
     // case BT_UNWINDWORD:
     case BT_FLOAT: return m_ctxt->get_type (GCC_JIT_TYPE_FLOAT);
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index 1a8cd8bac7b..8c52ddf80e1 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_COMPLEX_LONG_DOUBLE + 1;
+const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_INT128_T + 1;
 
 /* This comment is included by the docs.
 
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index d1835c79863..4683e862611 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -237,6 +237,36 @@ get_tree_node_for_type (enum gcc_jit_types type_)
     case GCC_JIT_TYPE_UNSIGNED_INT:
       return unsigned_type_node;
 
+    case GCC_JIT_TYPE_UINT8_T:
+      return unsigned_intQI_type_node;
+    case GCC_JIT_TYPE_UINT16_T:
+      return uint16_type_node;
+    case GCC_JIT_TYPE_UINT32_T:
+      return uint32_type_node;
+    case GCC_JIT_TYPE_UINT64_T:
+      return uint64_type_node;
+    case GCC_JIT_TYPE_UINT128_T:
+      if (targetm.scalar_mode_supported_p (TImode))
+        return uint128_type_node;
+
+      add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_);
+      return NULL;
+
+    case GCC_JIT_TYPE_INT8_T:
+      return intQI_type_node;
+    case GCC_JIT_TYPE_INT16_T:
+      return intHI_type_node;
+    case GCC_JIT_TYPE_INT32_T:
+      return intSI_type_node;
+    case GCC_JIT_TYPE_INT64_T:
+      return intDI_type_node;
+    case GCC_JIT_TYPE_INT128_T:
+      if (targetm.scalar_mode_supported_p (TImode))
+        return intTI_type_node;
+
+      add_error (NULL, "gcc_jit_types value unsupported on this target: %i", type_);
+      return NULL;
+
     case GCC_JIT_TYPE_LONG:
       return long_integer_type_node;
     case GCC_JIT_TYPE_UNSIGNED_LONG:
@@ -268,6 +298,8 @@ get_tree_node_for_type (enum gcc_jit_types type_)
       return complex_long_double_type_node;
     }
 
+  add_error (NULL, "unrecognized (enum gcc_jit_types) value: %i", type_);
+
   return NULL;
 }
 
@@ -280,10 +312,7 @@ get_type (enum gcc_jit_types type_)
 {
   tree type_node = get_tree_node_for_type (type_);
   if (type_node == NULL)
-    {
-      add_error (NULL, "unrecognized (enum gcc_jit_types) value: %i", type_);
-      return NULL;
-    }
+    return NULL;
 
   return new type (type_node);
 }
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 1e3fadfacd7..4ffdad0665f 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -822,6 +822,10 @@ recording::context::get_int_type (int num_bytes, int is_signed)
     return get_type (is_signed
 		     ? GCC_JIT_TYPE_LONG_LONG
 		     : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
+  if (num_bits == 128)
+    return get_type (is_signed
+		     ? GCC_JIT_TYPE_INT128_T
+		     : GCC_JIT_TYPE_UINT128_T);
 
   /* Some other size, not corresponding to the C int types.  */
   /* To be written: support arbitrary other sizes, sharing by
@@ -2325,6 +2329,26 @@ recording::memento_of_get_type::get_size ()
     case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
       size = LONG_LONG_TYPE_SIZE;
       break;
+    case GCC_JIT_TYPE_UINT8_T:
+    case GCC_JIT_TYPE_INT8_T:
+      size = 8;
+      break;
+    case GCC_JIT_TYPE_UINT16_T:
+    case GCC_JIT_TYPE_INT16_T:
+      size = 16;
+      break;
+    case GCC_JIT_TYPE_UINT32_T:
+    case GCC_JIT_TYPE_INT32_T:
+      size = 32;
+      break;
+    case GCC_JIT_TYPE_UINT64_T:
+    case GCC_JIT_TYPE_INT64_T:
+      size = 64;
+      break;
+    case GCC_JIT_TYPE_UINT128_T:
+    case GCC_JIT_TYPE_INT128_T:
+      size = 128;
+      break;
     case GCC_JIT_TYPE_FLOAT:
       size = FLOAT_TYPE_SIZE;
       break;
@@ -2334,6 +2358,9 @@ recording::memento_of_get_type::get_size ()
     case GCC_JIT_TYPE_LONG_DOUBLE:
       size = LONG_DOUBLE_TYPE_SIZE;
       break;
+    case GCC_JIT_TYPE_SIZE_T:
+      size = MAX_BITS_PER_WORD;
+      break;
     default:
       /* As this function is called by
 	 'gcc_jit_global_set_initializer' and
@@ -2373,6 +2400,16 @@ recording::memento_of_get_type::dereference ()
     case GCC_JIT_TYPE_UNSIGNED_LONG:
     case GCC_JIT_TYPE_LONG_LONG:
     case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
+    case GCC_JIT_TYPE_UINT8_T:
+    case GCC_JIT_TYPE_UINT16_T:
+    case GCC_JIT_TYPE_UINT32_T:
+    case GCC_JIT_TYPE_UINT64_T:
+    case GCC_JIT_TYPE_UINT128_T:
+    case GCC_JIT_TYPE_INT8_T:
+    case GCC_JIT_TYPE_INT16_T:
+    case GCC_JIT_TYPE_INT32_T:
+    case GCC_JIT_TYPE_INT64_T:
+    case GCC_JIT_TYPE_INT128_T:
     case GCC_JIT_TYPE_FLOAT:
     case GCC_JIT_TYPE_DOUBLE:
     case GCC_JIT_TYPE_LONG_DOUBLE:
@@ -2425,6 +2462,16 @@ recording::memento_of_get_type::is_int () const
     case GCC_JIT_TYPE_UNSIGNED_LONG:
     case GCC_JIT_TYPE_LONG_LONG:
     case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
+    case GCC_JIT_TYPE_UINT8_T:
+    case GCC_JIT_TYPE_UINT16_T:
+    case GCC_JIT_TYPE_UINT32_T:
+    case GCC_JIT_TYPE_UINT64_T:
+    case GCC_JIT_TYPE_UINT128_T:
+    case GCC_JIT_TYPE_INT8_T:
+    case GCC_JIT_TYPE_INT16_T:
+    case GCC_JIT_TYPE_INT32_T:
+    case GCC_JIT_TYPE_INT64_T:
+    case GCC_JIT_TYPE_INT128_T:
       return true;
 
     case GCC_JIT_TYPE_FLOAT:
@@ -2448,6 +2495,60 @@ recording::memento_of_get_type::is_int () const
     }
 }
 
+/* Implementation of pure virtual hook recording::type::is_signed for
+   recording::memento_of_get_type.  */
+
+bool
+recording::memento_of_get_type::is_signed () const
+{
+  switch (m_kind)
+    {
+    default: gcc_unreachable ();
+
+    case GCC_JIT_TYPE_SIGNED_CHAR:
+    case GCC_JIT_TYPE_CHAR:
+    case GCC_JIT_TYPE_SHORT:
+    case GCC_JIT_TYPE_INT:
+    case GCC_JIT_TYPE_LONG:
+    case GCC_JIT_TYPE_LONG_LONG:
+    case GCC_JIT_TYPE_INT8_T:
+    case GCC_JIT_TYPE_INT16_T:
+    case GCC_JIT_TYPE_INT32_T:
+    case GCC_JIT_TYPE_INT64_T:
+    case GCC_JIT_TYPE_INT128_T:
+      return true;
+
+    case GCC_JIT_TYPE_VOID:
+    case GCC_JIT_TYPE_VOID_PTR:
+    case GCC_JIT_TYPE_BOOL:
+    case GCC_JIT_TYPE_UNSIGNED_CHAR:
+    case GCC_JIT_TYPE_UNSIGNED_SHORT:
+    case GCC_JIT_TYPE_UNSIGNED_INT:
+    case GCC_JIT_TYPE_UNSIGNED_LONG:
+    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
+    case GCC_JIT_TYPE_UINT8_T:
+    case GCC_JIT_TYPE_UINT16_T:
+    case GCC_JIT_TYPE_UINT32_T:
+    case GCC_JIT_TYPE_UINT64_T:
+    case GCC_JIT_TYPE_UINT128_T:
+
+    case GCC_JIT_TYPE_FLOAT:
+    case GCC_JIT_TYPE_DOUBLE:
+    case GCC_JIT_TYPE_LONG_DOUBLE:
+
+    case GCC_JIT_TYPE_CONST_CHAR_PTR:
+
+    case GCC_JIT_TYPE_SIZE_T:
+
+    case GCC_JIT_TYPE_FILE_PTR:
+
+    case GCC_JIT_TYPE_COMPLEX_FLOAT:
+    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
+    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
+      return false;
+    }
+}
+
 /* Implementation of pure virtual hook recording::type::is_float for
    recording::memento_of_get_type.  */
 
@@ -2478,6 +2579,16 @@ recording::memento_of_get_type::is_float () const
     case GCC_JIT_TYPE_UNSIGNED_LONG:
     case GCC_JIT_TYPE_LONG_LONG:
     case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
+    case GCC_JIT_TYPE_UINT8_T:
+    case GCC_JIT_TYPE_UINT16_T:
+    case GCC_JIT_TYPE_UINT32_T:
+    case GCC_JIT_TYPE_UINT64_T:
+    case GCC_JIT_TYPE_UINT128_T:
+    case GCC_JIT_TYPE_INT8_T:
+    case GCC_JIT_TYPE_INT16_T:
+    case GCC_JIT_TYPE_INT32_T:
+    case GCC_JIT_TYPE_INT64_T:
+    case GCC_JIT_TYPE_INT128_T:
       return false;
 
     case GCC_JIT_TYPE_FLOAT:
@@ -2531,6 +2642,16 @@ recording::memento_of_get_type::is_bool () const
     case GCC_JIT_TYPE_UNSIGNED_LONG:
     case GCC_JIT_TYPE_LONG_LONG:
     case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
+    case GCC_JIT_TYPE_UINT8_T:
+    case GCC_JIT_TYPE_UINT16_T:
+    case GCC_JIT_TYPE_UINT32_T:
+    case GCC_JIT_TYPE_UINT64_T:
+    case GCC_JIT_TYPE_UINT128_T:
+    case GCC_JIT_TYPE_INT8_T:
+    case GCC_JIT_TYPE_INT16_T:
+    case GCC_JIT_TYPE_INT32_T:
+    case GCC_JIT_TYPE_INT64_T:
+    case GCC_JIT_TYPE_INT128_T:
       return false;
 
     case GCC_JIT_TYPE_FLOAT:
@@ -2601,7 +2722,18 @@ static const char * const get_type_strings[] = {
 
   "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
   "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
-  "complex long double"  /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
+  "complex long double",  /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
+
+  "__uint8_t",    /* GCC_JIT_TYPE_UINT8_T */
+  "__uint16_t",   /* GCC_JIT_TYPE_UINT16_T */
+  "__uint32_t",   /* GCC_JIT_TYPE_UINT32_T */
+  "__uint64_t",   /* GCC_JIT_TYPE_UINT64_T */
+  "__uint128_t",  /* GCC_JIT_TYPE_UINT128_T */
+  "__int8_t",     /* GCC_JIT_TYPE_INT8_T */
+  "__int16_t",    /* GCC_JIT_TYPE_INT16_T */
+  "__int32_t",    /* GCC_JIT_TYPE_INT32_T */
+  "__int64_t",    /* GCC_JIT_TYPE_INT64_T */
+  "__int128_t",   /* GCC_JIT_TYPE_INT128_T */
 
 };
 
@@ -2637,7 +2769,17 @@ static const char * const get_type_enum_strings[] = {
   "GCC_JIT_TYPE_FILE_PTR",
   "GCC_JIT_TYPE_COMPLEX_FLOAT",
   "GCC_JIT_TYPE_COMPLEX_DOUBLE",
-  "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE"
+  "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE",
+  "GCC_JIT_TYPE_UINT8_T",
+  "GCC_JIT_TYPE_UINT16_T",
+  "GCC_JIT_TYPE_UINT32_T",
+  "GCC_JIT_TYPE_UINT64_T",
+  "GCC_JIT_TYPE_UINT128_T",
+  "GCC_JIT_TYPE_INT8_T",
+  "GCC_JIT_TYPE_INT16_T",
+  "GCC_JIT_TYPE_INT32_T",
+  "GCC_JIT_TYPE_INT64_T",
+  "GCC_JIT_TYPE_INT128_T",
 };
 
 void
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 846d65cb202..1804aaa6664 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -564,6 +564,7 @@ public:
   virtual bool is_void () const { return false; }
   virtual vector_type *is_vector () { return NULL; }
   virtual bool has_known_size () const { return true; }
+  virtual bool is_signed () const = 0;
 
   bool is_numeric () const
   {
@@ -604,12 +605,19 @@ public:
   bool accepts_writes_from (type *rtype) FINAL OVERRIDE
   {
     if (m_kind == GCC_JIT_TYPE_VOID_PTR)
+    {
       if (rtype->is_pointer ())
 	{
 	  /* LHS (this) is type (void *), and the RHS is a pointer:
 	     accept it:  */
 	  return true;
 	}
+    }
+    else if (is_int () && rtype->is_int () && get_size () == rtype->get_size () && is_signed () == rtype->is_signed ())
+    {
+      /* LHS (this) is an integer of the same size and sign as rtype.  */
+      return true;
+    }
 
     return type::accepts_writes_from (rtype);
   }
@@ -620,6 +628,7 @@ public:
   type *is_pointer () FINAL OVERRIDE { return dereference (); }
   type *is_array () FINAL OVERRIDE { return NULL; }
   bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
+  bool is_signed () const FINAL OVERRIDE;
 
 public:
   void replay_into (replayer *r) FINAL OVERRIDE;
@@ -653,6 +662,7 @@ public:
   bool is_bool () const FINAL OVERRIDE { return false; }
   type *is_pointer () FINAL OVERRIDE { return m_other_type; }
   type *is_array () FINAL OVERRIDE { return NULL; }
+  bool is_signed () const FINAL OVERRIDE { return false; }
 
 private:
   string * make_debug_string () FINAL OVERRIDE;
@@ -674,12 +684,15 @@ public:
 
   type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
 
+  size_t get_size () FINAL OVERRIDE { return m_other_type->get_size (); };
+
   bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
   bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
   bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
   type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
   type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
   struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); }
+  bool is_signed () const FINAL OVERRIDE { return m_other_type->is_signed (); }
 
 protected:
   type *m_other_type;
@@ -811,6 +824,7 @@ class array_type : public type
   type *is_pointer () FINAL OVERRIDE { return NULL; }
   type *is_array () FINAL OVERRIDE { return m_element_type; }
   int num_elements () { return m_num_elements; }
+  bool is_signed () const FINAL OVERRIDE { return false; }
 
   void replay_into (replayer *) FINAL OVERRIDE;
 
@@ -844,6 +858,7 @@ public:
   bool is_bool () const FINAL OVERRIDE { return false; }
   type *is_pointer () FINAL OVERRIDE { return NULL; }
   type *is_array () FINAL OVERRIDE { return NULL; }
+  bool is_signed () const FINAL OVERRIDE { return false; }
 
   void replay_into (replayer *) FINAL OVERRIDE;
 
@@ -957,6 +972,7 @@ public:
   bool is_bool () const FINAL OVERRIDE { return false; }
   type *is_pointer () FINAL OVERRIDE { return NULL; }
   type *is_array () FINAL OVERRIDE { return NULL; }
+  bool is_signed () const FINAL OVERRIDE { return false; }
 
   bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
 
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 4c352e8c93d..f09ba6c3e42 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -345,10 +345,12 @@ jit_error (gcc::jit::recording::context *ctxt,
    gcc::jit::recording::type::accepts_writes_from virtual function on
    LTYPE.  */
 
-static bool
-compatible_types (gcc::jit::recording::type *ltype,
-		  gcc::jit::recording::type *rtype)
+int
+gcc_jit_compatible_types (gcc_jit_type *ltype,
+			  gcc_jit_type *rtype)
 {
+  RETURN_VAL_IF_FAIL (ltype, 0, NULL, NULL, "NULL ltype");
+  RETURN_VAL_IF_FAIL (rtype, 0, NULL, NULL, "NULL rtype");
   return ltype->accepts_writes_from (rtype);
 }
 
@@ -456,7 +458,7 @@ gcc_jit_context_get_type (gcc_jit_context *ctxt,
   JIT_LOG_FUNC (ctxt->get_logger ());
   RETURN_NULL_IF_FAIL_PRINTF1 (
     (type >= GCC_JIT_TYPE_VOID
-     && type <= GCC_JIT_TYPE_FILE_PTR),
+     && type < NUM_GCC_JIT_TYPES),
     ctxt, NULL,
     "unrecognized value for enum gcc_jit_types: %i", type);
 
@@ -523,6 +525,20 @@ gcc_jit_type_get_volatile (gcc_jit_type *type)
   return (gcc_jit_type *)type->get_volatile ();
 }
 
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, the real work is done by the
+   gcc::jit::recording::type::get_size method, in
+   jit-recording.cc.  */
+
+ssize_t
+gcc_jit_type_get_size (gcc_jit_type *type)
+{
+  RETURN_VAL_IF_FAIL (type, -1, NULL, NULL, "NULL type");
+  RETURN_VAL_IF_FAIL (type->is_int (), -1, NULL, NULL, "only getting the size of an int type is supported for now");
+  return type->get_size ();
+}
+
 /* Public entrypoint.  See description in libgccjit.h.
 
    After error-checking, the real work is done by the
@@ -2119,7 +2135,7 @@ gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
   RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
   RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
   RETURN_NULL_IF_FAIL_PRINTF4 (
-    a->get_type ()->unqualified () == b->get_type ()->unqualified (),
+    gcc_jit_compatible_types ((gcc_jit_type*)a->get_type ()->unqualified (), (gcc_jit_type*)b->get_type ()->unqualified ()),
     ctxt, loc,
     "mismatching types for binary op:"
     " a: %s (type: %s) b: %s (type: %s)",
@@ -2228,8 +2244,8 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt,
 	param->get_type ()->get_debug_string ());
 
       RETURN_NULL_IF_FAIL_PRINTF6 (
-	compatible_types (param->get_type (),
-			  arg->get_type ()),
+	gcc_jit_compatible_types ((gcc_jit_type*) param->get_type (),
+			  (gcc_jit_type*) arg->get_type ()),
 	ctxt, loc,
 	"mismatching types for argument %d of function \"%s\":"
 	" assignment to param %s (type: %s) from %s (type: %s)",
@@ -2317,8 +2333,8 @@ gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,
 	param_type->get_debug_string ());
 
       RETURN_NULL_IF_FAIL_PRINTF6 (
-	compatible_types (param_type,
-			  arg->get_type ()),
+	gcc_jit_compatible_types ((gcc_jit_type*) param_type,
+			  (gcc_jit_type*) arg->get_type ()),
 	ctxt, loc,
 	"mismatching types for argument %d of fn_ptr: %s:"
 	" assignment to param %d (type: %s) from %s (type: %s)",
@@ -2729,8 +2745,8 @@ gcc_jit_block_add_assignment (gcc_jit_block *block,
   RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
   RETURN_IF_FAIL_PRINTF4 (
-    compatible_types (lvalue->get_type (),
-		      rvalue->get_type ()),
+    gcc_jit_compatible_types ((gcc_jit_type*) lvalue->get_type (),
+		      (gcc_jit_type*) rvalue->get_type ()),
     ctxt, loc,
     "mismatching types:"
     " assignment to %s (type: %s) from %s (type: %s)",
@@ -2775,8 +2791,8 @@ gcc_jit_block_add_assignment_op (gcc_jit_block *block,
     op);
   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
   RETURN_IF_FAIL_PRINTF4 (
-    compatible_types (lvalue->get_type (),
-		      rvalue->get_type ()),
+    gcc_jit_compatible_types ((gcc_jit_type*) lvalue->get_type (),
+		      (gcc_jit_type*) rvalue->get_type ()),
     ctxt, loc,
     "mismatching types:"
     " assignment to %s (type: %s) involving %s (type: %s)",
@@ -2932,9 +2948,9 @@ gcc_jit_block_end_with_return (gcc_jit_block *block,
   gcc::jit::recording::function *func = block->get_function ();
   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
   RETURN_IF_FAIL_PRINTF4 (
-    compatible_types (
-      func->get_return_type (),
-      rvalue->get_type ()),
+    gcc_jit_compatible_types (
+      (gcc_jit_type*) func->get_return_type (),
+      (gcc_jit_type*) rvalue->get_type ()),
     ctxt, loc,
     "mismatching types:"
     " return of %s (type: %s) in function %s (return type: %s)",
@@ -3932,8 +3948,8 @@ gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
       RETURN_NULL_IF_FAIL_PRINTF1 (
 	elements[i], ctxt, loc, "NULL elements[%zi]", i);
       RETURN_NULL_IF_FAIL_PRINTF4 (
-	compatible_types (element_type,
-			  elements[i]->get_type ()),
+	gcc_jit_compatible_types ((gcc_jit_type*) element_type,
+			  (gcc_jit_type*) elements[i]->get_type ()),
 	ctxt, loc,
 	"mismatching type for element[%zi] (expected type: %s): %s (type: %s)",
 	i,
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 2a5ffacb1fe..1d9da354f31 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -574,8 +574,19 @@ enum gcc_jit_types
   /* Complex numbers.  */
   GCC_JIT_TYPE_COMPLEX_FLOAT,
   GCC_JIT_TYPE_COMPLEX_DOUBLE,
-  GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
-
+  GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE,
+
+  /* Sized integer types.  */
+  GCC_JIT_TYPE_UINT8_T,
+  GCC_JIT_TYPE_UINT16_T,
+  GCC_JIT_TYPE_UINT32_T,
+  GCC_JIT_TYPE_UINT64_T,
+  GCC_JIT_TYPE_UINT128_T,
+  GCC_JIT_TYPE_INT8_T,
+  GCC_JIT_TYPE_INT16_T,
+  GCC_JIT_TYPE_INT32_T,
+  GCC_JIT_TYPE_INT64_T,
+  GCC_JIT_TYPE_INT128_T
 };
 
 extern gcc_jit_type *
@@ -601,6 +612,23 @@ gcc_jit_type_get_const (gcc_jit_type *type);
 extern gcc_jit_type *
 gcc_jit_type_get_volatile (gcc_jit_type *type);
 
+#define LIBGCCJIT_HAVE_SIZED_INTEGERS
+
+/* Given types LTYPE and RTYPE, return non-zero if they are compatible.
+   This API entrypoint was added in LIBGCCJIT_ABI_20; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS  */
+extern int
+gcc_jit_compatible_types (gcc_jit_type *ltype,
+			  gcc_jit_type *rtype);
+
+/* Given type "T", get its size.
+   This API entrypoint was added in LIBGCCJIT_ABI_20; you can test for its
+   presence using
+     #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS  */
+extern ssize_t
+gcc_jit_type_get_size (gcc_jit_type *type);
+
 /* Given type "T", get type "T[N]" (for a constant N).  */
 extern gcc_jit_type *
 gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index f373fd39ac7..1c002786e84 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -243,3 +243,9 @@ LIBGCCJIT_ABI_19 {
     gcc_jit_context_new_union_constructor;
     gcc_jit_global_set_initializer_rvalue;
 } LIBGCCJIT_ABI_18;
+
+LIBGCCJIT_ABI_20 {
+  global:
+    gcc_jit_compatible_types;
+    gcc_jit_type_get_size;
+} LIBGCCJIT_ABI_19;
diff --git a/gcc/testsuite/jit.dg/test-types.c b/gcc/testsuite/jit.dg/test-types.c
index 8debcd7eb82..6836597d14e 100644
--- a/gcc/testsuite/jit.dg/test-types.c
+++ b/gcc/testsuite/jit.dg/test-types.c
@@ -1,3 +1,4 @@
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stddef.h>
@@ -29,6 +30,21 @@ struct zoo
   long long m_long_long;
   unsigned long long m_unsigned_long_long;
 
+  uint8_t m_u8;
+  uint16_t m_u16;
+  uint32_t m_u32;
+  uint64_t m_u64;
+
+  int8_t m_i8;
+  int16_t m_i16;
+  int32_t m_i32;
+  int64_t m_i64;
+
+#ifdef __SIZEOF_INT128__
+  __uint128_t m_u128;
+  __int128_t m_i128;
+#endif
+
   int m_sized_int_type;
 
   float m_float;
@@ -101,6 +117,31 @@ create_code (gcc_jit_context *ctxt, void *user_data)
   gcc_jit_field *field_m_unsigned_long_long =
     CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG_LONG, "m_unsigned_long_long");
 
+  gcc_jit_field *field_m_u8 =
+    CREATE_FIELD (GCC_JIT_TYPE_UINT8_T, "m_u8");
+  gcc_jit_field *field_m_u16 =
+    CREATE_FIELD (GCC_JIT_TYPE_UINT16_T, "m_u16");
+  gcc_jit_field *field_m_u32 =
+    CREATE_FIELD (GCC_JIT_TYPE_UINT32_T, "m_u32");
+  gcc_jit_field *field_m_u64 =
+    CREATE_FIELD (GCC_JIT_TYPE_UINT64_T, "m_u64");
+
+  gcc_jit_field *field_m_i8 =
+    CREATE_FIELD (GCC_JIT_TYPE_INT8_T, "m_i8");
+  gcc_jit_field *field_m_i16 =
+    CREATE_FIELD (GCC_JIT_TYPE_INT16_T, "m_i16");
+  gcc_jit_field *field_m_i32 =
+    CREATE_FIELD (GCC_JIT_TYPE_INT32_T, "m_i32");
+  gcc_jit_field *field_m_i64 =
+    CREATE_FIELD (GCC_JIT_TYPE_INT64_T, "m_i64");
+
+#ifdef __SIZEOF_INT128__
+  gcc_jit_field *field_m_u128 =
+    CREATE_FIELD (GCC_JIT_TYPE_UINT128_T, "m_u128");
+  gcc_jit_field *field_m_i128 =
+    CREATE_FIELD (GCC_JIT_TYPE_INT128_T, "m_i128");
+#endif
+
   /* Signed int type with sizeof (int): */
   gcc_jit_type *sized_int_type =
     gcc_jit_context_get_int_type (ctxt, sizeof (int), 1);
@@ -147,6 +188,21 @@ create_code (gcc_jit_context *ctxt, void *user_data)
     field_m_long_long,
     field_m_unsigned_long_long,
 
+    field_m_u8,
+    field_m_u16,
+    field_m_u32,
+    field_m_u64,
+
+    field_m_i8,
+    field_m_i16,
+    field_m_i32,
+    field_m_i64,
+
+#ifdef __SIZEOF_INT128__
+    field_m_u128,
+    field_m_i128,
+#endif
+
     field_m_sized_int_type,
 
     field_m_float,
@@ -266,6 +322,61 @@ create_code (gcc_jit_context *ctxt, void *user_data)
       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG),
       123456789))
 
+  ASSIGN(field_m_u8,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT8_T),
+      123))
+  ASSIGN(field_m_u16,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT16_T),
+      12345))
+  ASSIGN(field_m_u32,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT32_T),
+      123456789))
+  ASSIGN(field_m_u64,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT64_T),
+      123456789))
+
+  ASSIGN(field_m_i8,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT8_T),
+      -1))
+  ASSIGN(field_m_i16,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT16_T),
+      -2))
+  ASSIGN(field_m_i32,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT32_T),
+      -3))
+  ASSIGN(field_m_i64,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT64_T),
+      -4))
+
+#ifdef __SIZEOF_INT128__
+  ASSIGN(field_m_u128,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UINT128_T),
+      123456789))
+  ASSIGN(field_m_i128,
+    gcc_jit_context_new_rvalue_from_int (
+      ctxt,
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT128_T),
+      -5))
+#endif
+
   ASSIGN(field_m_sized_int_type,
     gcc_jit_context_new_rvalue_from_int (
       ctxt,
@@ -347,6 +458,21 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
   CHECK_VALUE (z.m_long_long, -42);
   CHECK_VALUE (z.m_unsigned_long_long, 123456789);
 
+  CHECK_VALUE (z.m_u8, 123);
+  CHECK_VALUE (z.m_u16, 12345);
+  CHECK_VALUE (z.m_u32, 123456789);
+  CHECK_VALUE (z.m_u64, 123456789);
+
+  CHECK_VALUE (z.m_i8, -1);
+  CHECK_VALUE (z.m_i16, -2);
+  CHECK_VALUE (z.m_i32, -3);
+  CHECK_VALUE (z.m_i64, -4);
+
+#ifdef __SIZEOF_INT128__
+  CHECK_VALUE (z.m_u128, 123456789);
+  CHECK_VALUE (z.m_i128, -5);
+#endif
+
   CHECK_VALUE (z.m_sized_int_type, 500);
 
   CHECK_VALUE (z.m_float, 3.141f);
@@ -358,4 +484,9 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
   CHECK_VALUE (z.m_size_t, sizeof (struct zoo));
 
   CHECK_VALUE (z.m_FILE_ptr, stderr);
+
+  if (sizeof(long) == 8)
+    CHECK (gcc_jit_compatible_types (
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG),
+      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT64_T)));
 }
-- 
2.26.2.7.g19db9cfb68.dirty


  reply	other threads:[~2022-04-08 20:30 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-18 12:23 Antoni Boucher
2021-05-18 12:36 ` Antoni Boucher
2021-05-18 12:53 ` Jakub Jelinek
2021-05-20 19:25   ` David Malcolm
2022-01-04  3:13     ` Antoni Boucher
2022-01-21 16:22     ` Antoni Boucher
2022-04-08 20:29       ` Antoni Boucher [this message]
2022-04-12 21:32         ` David Malcolm

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=634faf0f0f7aab414fd2764b8bb794b4144a4a0b.camel@zoho.com \
    --to=bouanto@zoho.com \
    --cc=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@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).