--- gcc/wide-int.h.jj	2023-06-07 09:42:14.997126190 +0200
+++ gcc/wide-int.h	2023-08-28 15:09:06.498448770 +0200
@@ -1065,7 +1065,11 @@ namespace wi
 class GTY(()) wide_int_storage
 {
 private:
-  HOST_WIDE_INT val[WIDE_INT_MAX_ELTS];
+  union
+  {
+    HOST_WIDE_INT val[WIDE_INT_MAX_ELTS];
+    HOST_WIDE_INT *valp;
+  } GTY((skip)) u;
   unsigned int len;
   unsigned int precision;
 
@@ -1073,6 +1077,7 @@ public:
   wide_int_storage ();
   template <typename T>
   wide_int_storage (const T &);
+  ~wide_int_storage ();
 
   /* The standard generic_wide_int storage methods.  */
   unsigned int get_precision () const;
@@ -1104,7 +1109,7 @@ namespace wi
   };
 }
 
-inline wide_int_storage::wide_int_storage () {}
+inline wide_int_storage::wide_int_storage () : precision (0) {}
 
 /* Initialize the storage from integer X, in its natural precision.
    Note that we do not allow integers with host-dependent precision
@@ -1117,9 +1122,17 @@ inline wide_int_storage::wide_int_storag
   { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION); }
   WIDE_INT_REF_FOR (T) xi (x);
   precision = xi.precision;
+  if (UNLIKELY (precision > WIDE_INT_MAX_PRECISION))
+    u.valp = XNEWVEC (HOST_WIDE_INT, CEIL (precision, HOST_BITS_PER_WIDE_INT));
   wi::copy (*this, xi);
 }
 
+inline wide_int_storage::~wide_int_storage ()
+{
+  if (UNLIKELY (precision > WIDE_INT_MAX_PRECISION))
+    XDELETEVEC (u.valp);
+}
+
 template <typename T>
 inline wide_int_storage&
 wide_int_storage::operator = (const T &x)
@@ -1127,7 +1140,15 @@ wide_int_storage::operator = (const T &x
   { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision); }
   { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION); }
   WIDE_INT_REF_FOR (T) xi (x);
-  precision = xi.precision;
+  if (UNLIKELY (precision != xi.precision))
+    {
+      if (UNLIKELY (precision > WIDE_INT_MAX_PRECISION))
+	XDELETEVEC (u.valp);
+      precision = xi.precision;
+      if (UNLIKELY (precision > WIDE_INT_MAX_PRECISION))
+	u.valp = XNEWVEC (HOST_WIDE_INT,
+			  CEIL (precision, HOST_BITS_PER_WIDE_INT));
+    }
   wi::copy (*this, xi);
   return *this;
 }
@@ -1141,7 +1162,7 @@ wide_int_storage::get_precision () const
 inline const HOST_WIDE_INT *
 wide_int_storage::get_val () const
 {
-  return val;
+  return UNLIKELY (precision > WIDE_INT_MAX_PRECISION) ? u.valp : u.val;
 }
 
 inline unsigned int
@@ -1153,7 +1174,7 @@ wide_int_storage::get_len () const
 inline HOST_WIDE_INT *
 wide_int_storage::write_val ()
 {
-  return val;
+  return UNLIKELY (precision > WIDE_INT_MAX_PRECISION) ? u.valp : u.val;
 }
 
 inline void
@@ -1161,8 +1182,10 @@ wide_int_storage::set_len (unsigned int
 {
   len = l;
   if (!is_sign_extended && len * HOST_BITS_PER_WIDE_INT > precision)
-    val[len - 1] = sext_hwi (val[len - 1],
-			     precision % HOST_BITS_PER_WIDE_INT);
+    {
+      HOST_WIDE_INT &v = write_val ()[len - 1];
+      v = sext_hwi (v, precision % HOST_BITS_PER_WIDE_INT);
+    }
 }
 
 /* Treat X as having signedness SGN and convert it to a PRECISION-bit
@@ -1196,6 +1219,9 @@ wide_int_storage::create (unsigned int p
 {
   wide_int x;
   x.precision = precision;
+  if (UNLIKELY (precision > WIDE_INT_MAX_PRECISION))
+    x.u.valp = XNEWVEC (HOST_WIDE_INT,
+			CEIL (precision, HOST_BITS_PER_WIDE_INT));
   return x;
 }
 
--- gcc/value-range.h.jj	2023-08-08 15:55:09.619120863 +0200
+++ gcc/value-range.h	2023-08-28 15:08:51.295648228 +0200
@@ -624,7 +624,9 @@ irange::maybe_resize (int needed)
     {
       m_max_ranges = HARD_MAX_RANGES;
       wide_int *newmem = new wide_int[m_max_ranges * 2];
-      memcpy (newmem, m_base, sizeof (wide_int) * num_pairs () * 2);
+      unsigned n = num_pairs () * 2;
+      for (unsigned i = 0; i < n; ++i)
+	newmem[i] = m_base[i];
       m_base = newmem;
     }
 }
--- gcc/wide-int.cc.jj	2023-08-08 15:55:09.621120835 +0200
+++ gcc/wide-int.cc	2023-08-28 15:29:48.620086813 +0200
@@ -2617,6 +2617,110 @@ wide_int_cc_tests ()
 	     wi::shifted_mask (0, 128, false, 128));
   ASSERT_EQ (wi::mask (128, true, 128),
 	     wi::shifted_mask (0, 128, true, 128));
+  const HOST_WIDE_INT a[192] = {
+    HOST_WIDE_INT_UC (0x0b2b03862d1fbe27), HOST_WIDE_INT_UC (0x444bb6ac06835f26),
+    HOST_WIDE_INT_UC (0x9d930632270edc17), HOST_WIDE_INT_UC (0xf9f1f7b1a4d298d3),
+    HOST_WIDE_INT_UC (0x1f87ccdd7b021c38), HOST_WIDE_INT_UC (0xf0366f9e68bbcdb2),
+    HOST_WIDE_INT_UC (0x2fcbfa32959408aa), HOST_WIDE_INT_UC (0xbdf7d4beb7b3dbe7),
+    HOST_WIDE_INT_UC (0x4a64ba19bdf3363f), HOST_WIDE_INT_UC (0x145c2ec5ae314c2f),
+    HOST_WIDE_INT_UC (0x307bf01303ca99d5), HOST_WIDE_INT_UC (0x82cac09501c0df1c),
+    HOST_WIDE_INT_UC (0x8119188bcf59391d), HOST_WIDE_INT_UC (0xd24ac359b0510387),
+    HOST_WIDE_INT_UC (0x1b6f9cd3e388da86), HOST_WIDE_INT_UC (0x4e2990a31337004a),
+    HOST_WIDE_INT_UC (0xd62f16910ab640ae), HOST_WIDE_INT_UC (0xa34a6f3c87668eaa),
+    HOST_WIDE_INT_UC (0x37e46f52b873eb07), HOST_WIDE_INT_UC (0xa498e8e255eaa65c),
+    HOST_WIDE_INT_UC (0x2370a16cbbdaa0af), HOST_WIDE_INT_UC (0x4f305e68993df752),
+    HOST_WIDE_INT_UC (0x074d3e131bd30499), HOST_WIDE_INT_UC (0xf4caf8393dbd01c4),
+    HOST_WIDE_INT_UC (0xb9e6794f494b3934), HOST_WIDE_INT_UC (0x7d7b2cc51969de8e),
+    HOST_WIDE_INT_UC (0x87494b790cce95f1), HOST_WIDE_INT_UC (0xeba990c44573c5c8),
+    HOST_WIDE_INT_UC (0x755007ea9663d2ea), HOST_WIDE_INT_UC (0xe5afe63b489e3d19),
+    HOST_WIDE_INT_UC (0x82138483f2c2831c), HOST_WIDE_INT_UC (0x5488d7a6d99ce301),
+    HOST_WIDE_INT_UC (0xd1d713ee75465be7), HOST_WIDE_INT_UC (0x29222cca5699b802),
+    HOST_WIDE_INT_UC (0x28e6308201df3eff), HOST_WIDE_INT_UC (0x720e2cef5151c53d),
+    HOST_WIDE_INT_UC (0xac381f111d9e336d), HOST_WIDE_INT_UC (0xfe4ae42ca0336dee),
+    HOST_WIDE_INT_UC (0xebd720f35a1baebc), HOST_WIDE_INT_UC (0x4fd3dbbf7d4324d6),
+    HOST_WIDE_INT_UC (0x4d78cb3165e57f22), HOST_WIDE_INT_UC (0x62e39c282e564f40),
+    HOST_WIDE_INT_UC (0x58a8b34a0882fabb), HOST_WIDE_INT_UC (0xbd6a54b970aa6765),
+    HOST_WIDE_INT_UC (0x12f7298ae3ec1a4e), HOST_WIDE_INT_UC (0xb3dfe9e1c64aba27),
+    HOST_WIDE_INT_UC (0xf5ae414ef25fcfb0), HOST_WIDE_INT_UC (0x6bd04f05fc0656ae),
+    HOST_WIDE_INT_UC (0x61c83d0178ecc390), HOST_WIDE_INT_UC (0xbe5310392ee661d9),
+    HOST_WIDE_INT_UC (0xb1ef589359431e81), HOST_WIDE_INT_UC (0x187f0dbf9a2cb650),
+    HOST_WIDE_INT_UC (0xab7b6664a0b0aec2), HOST_WIDE_INT_UC (0x287a358e7bdad628),
+    HOST_WIDE_INT_UC (0xb6853808e16aeb8b), HOST_WIDE_INT_UC (0x2268d04ba71b1ff7),
+    HOST_WIDE_INT_UC (0xadd0a43eb925494a), HOST_WIDE_INT_UC (0xaabe8fa96600a548),
+    HOST_WIDE_INT_UC (0x4f9a6641525c31e3), HOST_WIDE_INT_UC (0x90fd1e86293f4bd4),
+    HOST_WIDE_INT_UC (0xe2ad2b5c90e9800b), HOST_WIDE_INT_UC (0x914e8dacffa771fc),
+    HOST_WIDE_INT_UC (0xab104f92f2b7f5f0), HOST_WIDE_INT_UC (0x7ba77c13f62c21c4),
+
+    HOST_WIDE_INT_UC (0x004eb118946c8b0a), HOST_WIDE_INT_UC (0xcd10ba90ac387e24),
+    HOST_WIDE_INT_UC (0x3165a4c40640630e), HOST_WIDE_INT_UC (0x76dbccb2bb28b589),
+    HOST_WIDE_INT_UC (0x78c7d08d1846ba72), HOST_WIDE_INT_UC (0x088dadabc29b7eee),
+    HOST_WIDE_INT_UC (0xce09b01b92a09c9f), HOST_WIDE_INT_UC (0x5a3020593ce05c03),
+    HOST_WIDE_INT_UC (0x2bdc49e21551752d), HOST_WIDE_INT_UC (0x0c68f10ea335eed3),
+    HOST_WIDE_INT_UC (0xc7eeacac4c89f081), HOST_WIDE_INT_UC (0x1709baf3ff0cbf03),
+    HOST_WIDE_INT_UC (0x30f6ee76b7390893), HOST_WIDE_INT_UC (0x34837770023b44df),
+    HOST_WIDE_INT_UC (0x03bb2fa9e55edd44), HOST_WIDE_INT_UC (0xdcde0127dcf651cc),
+    HOST_WIDE_INT_UC (0xddf5b10f46c14a92), HOST_WIDE_INT_UC (0x5fd6a6333b7fc3d4),
+    HOST_WIDE_INT_UC (0xf00d6a63a6292f33), HOST_WIDE_INT_UC (0x4c1b946f4bfdf52a),
+    HOST_WIDE_INT_UC (0x995e31dd31510f3b), HOST_WIDE_INT_UC (0x8d35a772d465d990),
+    HOST_WIDE_INT_UC (0xdef217407399bfcc), HOST_WIDE_INT_UC (0x0afb0b5823306986),
+    HOST_WIDE_INT_UC (0xbb3485a144d31f32), HOST_WIDE_INT_UC (0x59f476dbe59fbd66),
+    HOST_WIDE_INT_UC (0x63ae89916180817f), HOST_WIDE_INT_UC (0xee37dbd94e282511),
+    HOST_WIDE_INT_UC (0x811c761fe6104d7e), HOST_WIDE_INT_UC (0x1ed873f682f029e2),
+    HOST_WIDE_INT_UC (0xc23b89782db3f7f0), HOST_WIDE_INT_UC (0x98dee95dea174c4c),
+    HOST_WIDE_INT_UC (0x5f91f3949dc9992e), HOST_WIDE_INT_UC (0xc36ae182d8aa7d32),
+    HOST_WIDE_INT_UC (0x61abef3db5f22a7f), HOST_WIDE_INT_UC (0x91ce45bbc50c2eef),
+    HOST_WIDE_INT_UC (0x5ab513c1350cd605), HOST_WIDE_INT_UC (0xcad14061bf6ec9fb),
+    HOST_WIDE_INT_UC (0x29557d00db0a03ed), HOST_WIDE_INT_UC (0xd084f8402af7c773),
+    HOST_WIDE_INT_UC (0x3becec18677ff915), HOST_WIDE_INT_UC (0x12bfce5297ee2e67),
+    HOST_WIDE_INT_UC (0x49328e0ad6868d03), HOST_WIDE_INT_UC (0xae508be370a5fe87),
+    HOST_WIDE_INT_UC (0xd04dbe85dd7b93e0), HOST_WIDE_INT_UC (0x2c8c32cb40d820db),
+    HOST_WIDE_INT_UC (0x17a33407c1a4f783), HOST_WIDE_INT_UC (0x0333bdab351f1a1b),
+    HOST_WIDE_INT_UC (0x9bf82ce2b590bd0e), HOST_WIDE_INT_UC (0xc28894ae9eb4a655),
+    HOST_WIDE_INT_UC (0xe5f78919f01d70f0), HOST_WIDE_INT_UC (0x597376afa702626f),
+    HOST_WIDE_INT_UC (0xb7e652d747bd63da), HOST_WIDE_INT_UC (0xffa518a4ec1620f7),
+    HOST_WIDE_INT_UC (0xc7e3951a33f99457), HOST_WIDE_INT_UC (0x939c109b56348cb2),
+    HOST_WIDE_INT_UC (0x0ba1c65a20616b8c), HOST_WIDE_INT_UC (0x230611c1a547fd7b),
+    HOST_WIDE_INT_UC (0x5c9356e353506379), HOST_WIDE_INT_UC (0x6c32318308ba24f1),
+    HOST_WIDE_INT_UC (0xd6c4a34b4f7f9a10), HOST_WIDE_INT_UC (0x26d3a3979e9e363c),
+    HOST_WIDE_INT_UC (0xe8a16f6587bffa80), HOST_WIDE_INT_UC (0xc1ed972017d689a0),
+
+    HOST_WIDE_INT_UC (0x0b79b49ec18c4931), HOST_WIDE_INT_UC (0x115c713cb2bbdd4a),
+    HOST_WIDE_INT_UC (0xcef8aaf62d4f3f26), HOST_WIDE_INT_UC (0x70cdc4645ffb4e5c),
+    HOST_WIDE_INT_UC (0x984f9d6a9348d6ab), HOST_WIDE_INT_UC (0xf8c41d4a2b574ca0),
+    HOST_WIDE_INT_UC (0xfdd5aa4e2834a549), HOST_WIDE_INT_UC (0x1827f517f49437ea),
+    HOST_WIDE_INT_UC (0x764103fbd344ab6d), HOST_WIDE_INT_UC (0x20c51fd451673b02),
+    HOST_WIDE_INT_UC (0xf86a9cbf50548a56), HOST_WIDE_INT_UC (0x99d47b8900cd9e1f),
+    HOST_WIDE_INT_UC (0xb2100702869241b0), HOST_WIDE_INT_UC (0x06ce3ac9b28c4866),
+    HOST_WIDE_INT_UC (0x1f2acc7dc8e7b7cb), HOST_WIDE_INT_UC (0x2b0791caf02d5216),
+    HOST_WIDE_INT_UC (0xb424c7a051778b41), HOST_WIDE_INT_UC (0x0321156fc2e6527f),
+    HOST_WIDE_INT_UC (0x27f1d9b65e9d1a3b), HOST_WIDE_INT_UC (0xf0b47d51a1e89b87),
+    HOST_WIDE_INT_UC (0xbcced349ed2bafea), HOST_WIDE_INT_UC (0xdc6605db6da3d0e2),
+    HOST_WIDE_INT_UC (0xe63f55538f6cc465), HOST_WIDE_INT_UC (0xffc6039160ed6b4a),
+    HOST_WIDE_INT_UC (0x751afef08e1e5866), HOST_WIDE_INT_UC (0xd76fa3a0ff099bf5),
+    HOST_WIDE_INT_UC (0xeaf7d50a6e4f1770), HOST_WIDE_INT_UC (0xd9e16c9d939bead9),
+    HOST_WIDE_INT_UC (0xf66c7e0a7c742069), HOST_WIDE_INT_UC (0x04885a31cb8e66fb),
+    HOST_WIDE_INT_UC (0x444f0dfc20767b0d), HOST_WIDE_INT_UC (0xed67c104c3b42f4e),
+    HOST_WIDE_INT_UC (0x31690783130ff515), HOST_WIDE_INT_UC (0xec8d0e4d2f443535),
+    HOST_WIDE_INT_UC (0x8a921fbfb7d1697e), HOST_WIDE_INT_UC (0x03dc72ab165df42c),
+    HOST_WIDE_INT_UC (0x06ed32d252ab0973), HOST_WIDE_INT_UC (0xc91c248e5fa237ea),
+    HOST_WIDE_INT_UC (0x152c9df43525b2aa), HOST_WIDE_INT_UC (0x2058d3ffa83aec4a),
+    HOST_WIDE_INT_UC (0x8965b749cd657838), HOST_WIDE_INT_UC (0x75a36a7ac6447da7),
+    HOST_WIDE_INT_UC (0xa1db4154df0987be), HOST_WIDE_INT_UC (0x6bbae09ce15065ec),
+    HOST_WIDE_INT_UC (0xe344e810c167ae2f), HOST_WIDE_INT_UC (0xe06c1cad0722db02),
+    HOST_WIDE_INT_UC (0x0d517556b404c733), HOST_WIDE_INT_UC (0x6f040cb1312570ca),
+    HOST_WIDE_INT_UC (0xfdc069e42e7d809e), HOST_WIDE_INT_UC (0x80dba4e7cd9b082e),
+    HOST_WIDE_INT_UC (0x97e6e1ad49608f72), HOST_WIDE_INT_UC (0x71f2846f412f18c0),
+    HOST_WIDE_INT_UC (0x6361b93be86e129c), HOST_WIDE_INT_UC (0x281f4e3367f0f720),
+    HOST_WIDE_INT_UC (0x7e68cd2315647fe3), HOST_WIDE_INT_UC (0xb604e0e6fd4facaa),
+    HOST_WIDE_INT_UC (0xb9726a98d986b4d6), HOST_WIDE_INT_UC (0xcdc4a16b0b48a2c3),
+    HOST_WIDE_INT_UC (0xac2dbd24a5ac955c), HOST_WIDE_INT_UC (0xfd2f500931f970c5),
+    HOST_WIDE_INT_UC (0xb971cea7e0691a1b), HOST_WIDE_INT_UC (0xb82231449e45a839),
+    HOST_WIDE_INT_UC (0x93b1bef87a77f070), HOST_WIDE_INT_UC (0x3d9513340e02ab65)
+  };
+  wide_int b = wide_int::from_array (&a[0], 64, 4096);
+  wide_int c = wide_int::from_array (&a[64], 64, 4096);
+  wide_int d = wide_int::from_array (&a[128], 64, 4096);
+  ASSERT_EQ (b + c, d);
 }
 
 } // namespace selftest
