diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 99055523d915a4ca9dfbf55d170fd5561ee8e961..8aab9ea0bae00a958ea53e84362c712f9d83d1f7 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -5173,7 +5173,6 @@ trees_out::start (tree t, bool code_streamed)
       break;
 
     case FIXED_CST:
-    case POLY_INT_CST:
       gcc_unreachable (); /* Not supported in C++.  */
       break;
 
@@ -5259,7 +5258,6 @@ trees_in::start (unsigned code)
 
     case FIXED_CST:
     case IDENTIFIER_NODE:
-    case POLY_INT_CST:
     case SSA_NAME:
     case TARGET_MEM_REF:
     case TRANSLATION_UNIT_DECL:
@@ -6106,7 +6104,10 @@ trees_out::core_vals (tree t)
       break;
 
     case POLY_INT_CST:
-      gcc_unreachable (); /* Not supported in C++.  */
+      if (streaming_p ())
+	for (unsigned ix = 0; ix != NUM_POLY_INT_COEFFS; ix++)
+	  WT (POLY_INT_CST_COEFF (t, ix));
+      break;
 
     case REAL_CST:
       if (streaming_p ())
@@ -6615,8 +6616,9 @@ trees_in::core_vals (tree t)
       break;
 
     case POLY_INT_CST:
-      /* Not suported in C++.  */
-      return false;
+      for (unsigned ix = 0; ix != NUM_POLY_INT_COEFFS; ix++)
+	RT (POLY_INT_CST_COEFF (t, ix));
+      break;
 
     case REAL_CST:
       if (const void *bytes = buf (sizeof (real_value)))
@@ -9068,8 +9070,8 @@ trees_out::type_node (tree type)
       if (streaming_p ())
 	{
 	  poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type);
-	  /* to_constant asserts that only coeff[0] is of interest.  */
-	  wu (static_cast<unsigned HOST_WIDE_INT> (nunits.to_constant ()));
+	  for (unsigned ix = 0; ix != NUM_POLY_INT_COEFFS; ix++)
+	    wu (nunits.coeffs[ix]);
 	}
       break;
     }
@@ -9630,9 +9632,11 @@ trees_in::tree_node (bool is_use)
 
 	  case VECTOR_TYPE:
 	    {
-	      unsigned HOST_WIDE_INT nunits = wu ();
+	      poly_uint64 nunits;
+	      for (unsigned ix = 0; ix != NUM_POLY_INT_COEFFS; ix++)
+		nunits.coeffs[ix] = wu ();
 	      if (!get_overrun ())
-		res = build_vector_type (res, static_cast<poly_int64> (nunits));
+		res = build_vector_type (res, nunits);
 	    }
 	    break;
 	  }
@@ -20151,7 +20155,7 @@ init_modules (cpp_reader *reader)
      some global trees are lazily created and we don't want that to
      mess with our syndrome of fixed trees.  */
   unsigned crc = 0;
-  vec_alloc (fixed_trees, 200);
+  vec_alloc (fixed_trees, 250);
 
   dump () && dump ("+Creating globals");
   /* Insert the TRANSLATION_UNIT_DECL.  */
@@ -20169,6 +20173,14 @@ init_modules (cpp_reader *reader)
 	  dump () && dump ("+%u", v);
 	}
     }
+  /* OS- and machine-specific types are dynamically registered at
+     runtime, so cannot be part of global_tree_arys.  */
+  registered_builtin_types && dump ("") && dump ("+\tB:");
+  for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
+    {
+      unsigned v = maybe_add_global (TREE_VALUE (t), crc);
+      dump () && dump ("+%u", v);
+    }
   global_crc = crc32_unsigned (crc, fixed_trees->length ());
   dump ("") && dump ("Created %u unique globals, crc=%x",
 		     fixed_trees->length (), global_crc);
diff --git a/gcc/testsuite/g++.dg/modules/target-aarch64-1_a.C b/gcc/testsuite/g++.dg/modules/target-aarch64-1_a.C
new file mode 100644
index 0000000000000000000000000000000000000000..6c699053cdc5fd4f9568aa862fa01be3fd88456e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/target-aarch64-1_a.C
@@ -0,0 +1,17 @@
+// PR c++/111224
+// { dg-do compile { target aarch64*-*-* } }
+// { dg-require-effective-target aarch64_asm_sve_ok }
+// { dg-additional-options "-fmodules-ts -march=armv8.2-a+sve" }
+
+module;
+
+// We can't do a header unit of this right now because this
+// uses target attributes, that we don't yet support.
+// See also PR c++/108080.
+#include <arm_sve.h>
+
+export module M;
+
+export inline void foo(svbool_t x, svfloat16_t f) {
+  svabs_f16_x(x, f);
+}
diff --git a/gcc/testsuite/g++.dg/modules/target-aarch64-1_b.C b/gcc/testsuite/g++.dg/modules/target-aarch64-1_b.C
new file mode 100644
index 0000000000000000000000000000000000000000..c18691dcf8a688515f4523602c8523e090c1ad24
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/target-aarch64-1_b.C
@@ -0,0 +1,13 @@
+// PR c++/111224
+// { dg-module-do link { target aarch64*-*-* } }
+// { dg-require-effective-target aarch64_asm_sve_ok }
+// { dg-additional-options "-fmodules-ts -fno-module-lazy -march=armv8.2-a+sve" }
+
+#include <arm_sve.h>
+import M;
+
+int main() {
+  svbool_t x = svptrue_b8 ();
+  svfloat16_t f = svdup_n_f16(1.0);
+  foo(x, f);
+}
diff --git a/gcc/testsuite/g++.dg/modules/target-powerpc-1_a.C b/gcc/testsuite/g++.dg/modules/target-powerpc-1_a.C
new file mode 100644
index 0000000000000000000000000000000000000000..693ed101ed5d6d5d68affb81a73ddb2fb9a842be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/target-powerpc-1_a.C
@@ -0,0 +1,7 @@
+// PR c++/98645
+// { dg-do compile { target powerpc*-*-* } }
+// { dg-require-effective-target ppc_float128_sw }
+// { dg-additional-options "-fmodules-ts -mfloat128 -mabi=ieeelongdouble" }
+
+export module M;
+export __ibm128 i = 0.0;
diff --git a/gcc/testsuite/g++.dg/modules/target-powerpc-1_b.C b/gcc/testsuite/g++.dg/modules/target-powerpc-1_b.C
new file mode 100644
index 0000000000000000000000000000000000000000..d6b684b556d08e2fb93dc8a18abcc062d3079646
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/target-powerpc-1_b.C
@@ -0,0 +1,10 @@
+// PR c++/98645
+// { dg-module-do compile { target powerpc*-*-* } }
+// { dg-require-effective-target ppc_float128_sw }
+// { dg-additional-options "-fmodules-ts -mfloat128 -mabi=ieeelongdouble" }
+
+import M;
+
+int main() {
+  __ibm128 j = i;
+}
diff --git a/gcc/testsuite/g++.dg/modules/target-powerpc-2_a.C b/gcc/testsuite/g++.dg/modules/target-powerpc-2_a.C
new file mode 100644
index 0000000000000000000000000000000000000000..cc18862e55ca889d89eca35b8562a45d151f5164
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/target-powerpc-2_a.C
@@ -0,0 +1,20 @@
+// PR c++/98688
+// { dg-do compile { target powerpc*-*-* } }
+// { dg-additional-options "-fmodules-ts -mcpu=power10 -mmma" }
+
+export module mma_foo0;
+
+typedef unsigned char  vec_t __attribute__((vector_size(16)));
+
+export void
+foo0 (__vector_quad *dst, vec_t *vec, __vector_pair *pvecp)
+{
+  __vector_quad acc;
+  __vector_pair vecp0 = *pvecp;
+  vec_t vec1 = vec[1];
+
+  __builtin_mma_xvf64ger (&acc, vecp0, vec1);
+  __builtin_mma_xvf64gerpp (&acc, vecp0, vec1);
+  __builtin_mma_xvf64gerpn (&acc, vecp0, vec1);
+  dst[0] = acc;
+}
diff --git a/gcc/testsuite/g++.dg/modules/target-powerpc-2_b.C b/gcc/testsuite/g++.dg/modules/target-powerpc-2_b.C
new file mode 100644
index 0000000000000000000000000000000000000000..9e77ba7afcadc6a9d3c8b0a5e688d82fd8f5fd65
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/target-powerpc-2_b.C
@@ -0,0 +1,12 @@
+// PR c++/98688
+// { dg-module-do compile { target powerpc*-*-* } }
+// { dg-additional-options "-fmodules-ts -mcpu=power10 -mmma" }
+
+import mma_foo0;
+
+typedef unsigned char  vec_t __attribute__((vector_size(16)));
+
+void bar(__vector_quad *dst, vec_t *vec, __vector_pair *pvecp)
+{
+    foo0 (dst, vec, pvecp);
+}