]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
bitintlower: Big-endian lowering support
authorJakub Jelinek <jakub@redhat.com>
Tue, 20 May 2025 06:18:58 +0000 (08:18 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 20 May 2025 06:18:58 +0000 (08:18 +0200)
The following patch adds big endian support to the bitintlower pass.
While the rest of the _BitInt support has been written with endianity
in mind, in the bitintlower pass I've written it solely little endian
at the start, because the pass is large and complicated and there were
no big-endian backends with _BitInt psABI at the point of writing it,
so the big-endian support would be completely untested.
Now that I got privately a patch to add s390x support, I went through
the whole pass and added the support.
Some months ago I've talked about two possibilities to do the big-endian
support, one perhaps easier would be keep the idx vars (INTEGER_CSTs
for bitint_prec_large and partially SSA_NAMEs, partially INTEGER_CSTs
for bitint_prec_huge) iterating like for little-endian from 0 upwards
and do the big-endian index correction only when accessing the limbs
(but mergeable casts between _BitInts with different number of limbs
would be a nightmare), which would have the disadvantage that we'd need
to wait until propagation and ivopts to fix stuff up (and not sure it
would be able to fix everything), or change stuff so that the idxes
used between the different bitint_large_huge class methods iterate on
big endian from highest down to 0.
The following patch implements the latter.
On s390x with the 3 patches from IBM without this patch I got on
make -j32 -k check-gcc GCC_TEST_RUN_EXPENSIVE=1 RUNTESTFLAGS="GCC_TEST_RUN_EXPENSIVE=1 dg.exp='*bitint* pr112673.c builtin-stdc-bit-*.c pr112566-2.c pr112511.c pr116588.c pr116003.c
+pr113693.c pr113602.c flex-array-counted-by-7.c' dg-torture.exp='*bitint* pr116480-2.c pr114312.c pr114121.c' dfp.exp=*bitint* vect.exp='vect-early-break_99-pr113287.c'
+tree-ssa.exp=pr113735.c"
347 FAILs, 326 out of that execution failures (and that doesn't include
some tests that happened to succeed by pure luck because e.g. comparisons
weren't implemented correctly).
With this patch (and 2 small patches I'm going to post next) I got this
down to
FAIL: gcc.dg/dfp/bitint-1.c (test for excess errors)
FAIL: gcc.dg/dfp/bitint-2.c (test for excess errors)
FAIL: gcc.dg/dfp/bitint-3.c (test for excess errors)
FAIL: gcc.dg/dfp/bitint-4.c (test for excess errors)
FAIL: gcc.dg/dfp/bitint-5.c (test for excess errors)
FAIL: gcc.dg/dfp/bitint-6.c (test for excess errors)
FAIL: gcc.dg/dfp/bitint-8.c (test for excess errors)
FAIL: gcc.dg/torture/bitint-64.c   -O3 -g  execution test
FAIL: gcc.dg/torture/bitint-64.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  execution test
where the dfp stuff is due to missing DPD dfp <-> _BitInt support
I'm working on next, and bitint-64.c is some expansion related
issue with _Atomic _BitInt(5) (will look at it later, but there
bitint lowering isn't involved at all).
Most of the patch just tweaks things so that it iterates in the
right direction, for casts with different number of limbs does the
needed index adjustments and unfortunately due to that (and e.g.
add/sub/mul overflow BE lowering) has some pessimizations on the
SSA conflict side; on little-endian mergeable ops have the
advantage that all the accesses iterate from index 0 up, so even
if there is e.g. overlap between the lhs and some used values, except
for mul/div where libgcc APIs require no overlap we don't need to
avoid it, all the limbs are updated in sync before going on to handle
next limb.  On big-endian, that isn't the case, casts etc. can result
in index adjustments and so we could overwrite a limb that will still
need to be processed as input.  So, there is a special case that looks
for different numbers of limbs among arguments and in that case marks
the lhs as conflicting with the inputs.

On little-endian, this patch shouldn't affect code generation, with
one little exception; in the separate_ext handling in lower_mergeable_stmt
the loop (if bitint_large_huge) was iterating using some idx and then
if bo_idx was non-zero, adding that constant to a new SSA_NAME and using
that to do the limb accesses.  As the limb accesses are the only place
where the idx is used (apart from the loop exit test), I've changed it
to iterate on idxes with bo_idx already added to those.

P.S., would be nice to eventually also enable big-endian aarch64,
but I don't have access to those, so can't test that myself.

P.S., at least in the current s390x patches it wants info->extended_p,
this patch doesn't change anything about that.  I believe most of the
time the _BitInt vars/params/return values are already extended, but
there is no testcase coverage for that, I will work on that incrementally
(and then perhaps arm 32-bit _BitInt support can be enabled too).

2025-05-20  Jakub Jelinek  <jakub@redhat.com>

* gimple-lower-bitint.cc (bitint_big_endian): New variable.
(bitint_precision_kind): Set it.
(struct bitint_large_huge): Add unsigned argument to
finish_arith_overflow.
(bitint_large_huge::limb_access_type): Handle bitint_big_endian.
(bitint_large_huge::handle_operand): Likewise.
(bitint_large_huge::handle_cast): Likewise.
(bitint_large_huge::handle_bit_field_ref): Likewise.
(bitint_large_huge::handle_load): Likewise.
(bitint_large_huge::lower_shift_stmt): Likewise.
(bitint_large_huge::finish_arith_overflow): Likewise.
Add nelts argument.
(bitint_large_huge::lower_addsub_overflow): Handle bitint_big_endian.
Adjust finish_arith_overflow caller.
(bitint_large_huge::lower_mul_overflow): Likewise.
(bitint_large_huge::lower_bit_query): Handle bitint_big_endian.
(bitint_large_huge::lower_stmt): Likewise.
(build_bitint_stmt_ssa_conflicts): Likewise.
(gimple_lower_bitint): Likewise.

* gcc.dg/torture/bitint-78.c: New test.
* gcc.dg/torture/bitint-79.c: New test.
* gcc.dg/torture/bitint-80.c: New test.
* gcc.dg/torture/bitint-81.c: New test.

gcc/gimple-lower-bitint.cc
gcc/testsuite/gcc.dg/torture/bitint-78.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/bitint-79.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/bitint-80.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/bitint-81.c [new file with mode: 0644]

index 6fefc8347629680be09b26d9a4d01245d4451ac8..ebd4e9864a19e254760cdbae136fe4725cbd0b0b 100644 (file)
@@ -77,6 +77,7 @@ enum bitint_prec_kind {
 
 static int small_max_prec, mid_min_prec, large_min_prec, huge_min_prec;
 static int limb_prec;
+static bool bitint_big_endian;
 
 /* Categorize _BitInt(PREC) as small, middle, large or huge.  */
 
@@ -101,6 +102,7 @@ bitint_precision_kind (int prec)
       small_max_prec = prec;
       return bitint_prec_small;
     }
+  bitint_big_endian = info.big_endian;
   if (!large_min_prec
       && GET_MODE_PRECISION (limb_mode) < MAX_FIXED_MODE_SIZE)
     large_min_prec = MAX_FIXED_MODE_SIZE + 1;
@@ -453,7 +455,7 @@ struct bitint_large_huge
   tree arith_overflow_extract_bits (unsigned int, unsigned int, tree,
                                    unsigned int, bool);
   void finish_arith_overflow (tree, tree, tree, tree, tree, tree, gimple *,
-                             tree_code);
+                             unsigned, tree_code);
   void lower_addsub_overflow (tree, gimple *);
   void lower_mul_overflow (tree, gimple *);
   void lower_cplxpart_stmt (tree, gimple *);
@@ -594,7 +596,9 @@ bitint_large_huge::limb_access_type (tree type, tree idx)
   unsigned HOST_WIDE_INT i = tree_to_uhwi (idx);
   unsigned int prec = TYPE_PRECISION (type);
   gcc_assert (i * limb_prec < prec);
-  if ((i + 1) * limb_prec <= prec)
+  if (bitint_big_endian
+      ? (i != 0 || (prec % limb_prec) == 0)
+      : (i + 1) * limb_prec <= prec)
     return m_limb_type;
   else
     return build_nonstandard_integer_type (prec % limb_prec,
@@ -886,6 +890,8 @@ bitint_large_huge::handle_operand (tree op, tree idx)
              m_data.safe_push (NULL_TREE);
              m_data.safe_push (NULL_TREE);
            }
+         if (bitint_big_endian)
+           i = CEIL (TYPE_PRECISION (TREE_TYPE (op)), limb_prec) - 1 - i;
          if (limb_prec != HOST_BITS_PER_WIDE_INT)
            {
              wide_int w = wi::rshift (wi::to_wide (op), i * limb_prec,
@@ -964,22 +970,41 @@ bitint_large_huge::handle_operand (tree op, tree idx)
              min_prec = CEIL (min_prec, 2 * limb_prec) * (2 * limb_prec);
              tree type = build_bitint_type (min_prec, 1);
              tree c = tree_output_constant_def (fold_convert (type, op));
-             tree idx2 = make_ssa_name (sizetype);
-             g = gimple_build_assign (idx2, PLUS_EXPR, idx, size_one_node);
+             tree ridx = idx;
+             if (bitint_big_endian)
+               {
+                 ridx = make_ssa_name (sizetype);
+                 g = gimple_build_assign (ridx, PLUS_EXPR, idx,
+                                          size_int (min_prec / limb_prec
+                                                    - ((HOST_WIDE_INT)
+                                                       CEIL (prec,
+                                                             limb_prec))));
+                 insert_before (g);
+               }
+             tree ridx2 = make_ssa_name (sizetype);
+             g = gimple_build_assign (ridx2, PLUS_EXPR, ridx,
+                                      bitint_big_endian
+                                      ? size_int (-1) : size_one_node);
              insert_before (g);
-             g = gimple_build_cond (LT_EXPR, idx,
-                                    size_int (min_prec / limb_prec),
-                                    NULL_TREE, NULL_TREE);
+             if (bitint_big_endian)
+               g = gimple_build_cond (GE_EXPR, idx,
+                                      size_int (CEIL (prec, limb_prec)
+                                                - min_prec / limb_prec),
+                                      NULL_TREE, NULL_TREE);
+             else
+               g = gimple_build_cond (LT_EXPR, idx,
+                                      size_int (min_prec / limb_prec),
+                                      NULL_TREE, NULL_TREE);
              edge edge_true, edge_false;
              if_then (g, (min_prec >= (prec - rem) / 2
                           ? profile_probability::likely ()
                           : profile_probability::unlikely ()),
                       edge_true, edge_false);
-             tree c1 = limb_access (TREE_TYPE (op), c, idx, false);
+             tree c1 = limb_access (TREE_TYPE (op), c, ridx, false);
              g = gimple_build_assign (make_ssa_name (TREE_TYPE (c1)), c1);
              insert_before (g);
              c1 = gimple_assign_lhs (g);
-             tree c2 = limb_access (TREE_TYPE (op), c, idx2, false);
+             tree c2 = limb_access (TREE_TYPE (op), c, ridx2, false);
              g = gimple_build_assign (make_ssa_name (TREE_TYPE (c2)), c2);
              insert_before (g);
              c2 = gimple_assign_lhs (g);
@@ -1014,33 +1039,46 @@ bitint_large_huge::handle_operand (tree op, tree idx)
              m_data[m_data_cnt + 1] = integer_type_node;
            }
          t = m_data[m_data_cnt];
-         if (m_data[m_data_cnt + 1] == NULL_TREE)
+       }
+      else
+       t = m_data[m_data_cnt + 1];
+      if (m_data[m_data_cnt + 1] == NULL_TREE)
+       {
+         tree ridx = idx;
+         unsigned int prec = TYPE_PRECISION (TREE_TYPE (op));
+         tree c = m_data[m_data_cnt];
+         unsigned int min_prec = TYPE_PRECISION (TREE_TYPE (c));
+         if (bitint_big_endian
+             && CEIL (min_prec, limb_prec) != CEIL (prec, limb_prec))
            {
-             t = limb_access (TREE_TYPE (op), t, idx, false);
-             g = gimple_build_assign (make_ssa_name (TREE_TYPE (t)), t);
+             ridx = make_ssa_name (sizetype);
+             g = gimple_build_assign (ridx, PLUS_EXPR, idx,
+                                      size_int (CEIL (min_prec, limb_prec)
+                                                - ((HOST_WIDE_INT)
+                                                   CEIL (prec, limb_prec))));
              insert_before (g);
-             t = gimple_assign_lhs (g);
            }
-       }
-      else if (m_data[m_data_cnt + 1] == NULL_TREE)
-       {
-         t = limb_access (TREE_TYPE (op), m_data[m_data_cnt], idx, false);
+         t = limb_access (TREE_TYPE (op), c, ridx, false);
          g = gimple_build_assign (make_ssa_name (TREE_TYPE (t)), t);
          insert_before (g);
          t = gimple_assign_lhs (g);
        }
-      else
-       t = m_data[m_data_cnt + 1];
-      if (m_data[m_data_cnt + 1] == integer_type_node)
+      else if (m_data[m_data_cnt + 1] == integer_type_node)
        {
          unsigned int prec = TYPE_PRECISION (TREE_TYPE (op));
          unsigned rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec);
          int ext = wi::neg_p (wi::to_wide (op)) ? -1 : 0;
          tree c = m_data[m_data_cnt];
          unsigned min_prec = TYPE_PRECISION (TREE_TYPE (c));
-         g = gimple_build_cond (LT_EXPR, idx,
-                                size_int (min_prec / limb_prec),
-                                NULL_TREE, NULL_TREE);
+         if (bitint_big_endian)
+           g = gimple_build_cond (GE_EXPR, idx,
+                                  size_int (CEIL (prec, limb_prec)
+                                            - min_prec / limb_prec),
+                                  NULL_TREE, NULL_TREE);
+         else
+           g = gimple_build_cond (LT_EXPR, idx,
+                                  size_int (min_prec / limb_prec),
+                                  NULL_TREE, NULL_TREE);
          edge edge_true, edge_false;
          if_then (g, (min_prec >= (prec - rem) / 2
                       ? profile_probability::likely ()
@@ -1048,7 +1086,18 @@ bitint_large_huge::handle_operand (tree op, tree idx)
                   edge_true, edge_false);
          if (min_prec > (unsigned) limb_prec)
            {
-             c = limb_access (TREE_TYPE (op), c, idx, false);
+             tree ridx = idx;
+             if (bitint_big_endian)
+               {
+                 ridx = make_ssa_name (sizetype);
+                 g = gimple_build_assign (ridx, PLUS_EXPR, idx,
+                                          size_int (min_prec / limb_prec
+                                                    - ((HOST_WIDE_INT)
+                                                       CEIL (prec,
+                                                             limb_prec))));
+                 insert_before (g);
+               }
+             c = limb_access (TREE_TYPE (op), c, ridx, false);
              g = gimple_build_assign (make_ssa_name (TREE_TYPE (c)), c);
              insert_before (g);
              c = gimple_assign_lhs (g);
@@ -1312,7 +1361,24 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
                      && (m_upwards_2limb * limb_prec
                          < TYPE_PRECISION (lhs_type))))))
        {
-         rhs1 = handle_operand (rhs1, idx);
+         tree ridx = idx;
+         if (bitint_big_endian
+             && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
+                 != CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
+           {
+             HOST_WIDE_INT diff = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
+             diff -= CEIL (TYPE_PRECISION (lhs_type), limb_prec);
+             if (tree_fits_uhwi_p (idx))
+               ridx = size_int (tree_to_uhwi (idx) + diff);
+             else
+               {
+                 tree t = make_ssa_name (sizetype);
+                 g = gimple_build_assign (t, PLUS_EXPR, idx, size_int (diff));
+                 insert_before (g);
+                 ridx = t;
+               }
+           }
+         rhs1 = handle_operand (rhs1, ridx);
          if (tree_fits_uhwi_p (idx))
            {
              tree type = limb_access_type (lhs_type, idx);
@@ -1327,6 +1393,8 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
                      - !TYPE_UNSIGNED (rhs_type)) / limb_prec;
       /* Indexes >= than this always contain an extension.  */
       unsigned high = CEIL ((unsigned) TYPE_PRECISION (rhs_type), limb_prec);
+      unsigned lcnt = CEIL ((unsigned) TYPE_PRECISION (lhs_type), limb_prec);
+      unsigned lowe = bitint_big_endian ? lcnt - 1 - low : low;
       bool save_first = m_first;
       if (m_first)
        {
@@ -1351,7 +1419,8 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
              else
                gsi_next (&m_gsi);
              m_data_cnt = save_data_cnt + 3;
-             t = handle_operand (rhs1, size_int (low));
+             t = handle_operand (rhs1, size_int (bitint_big_endian
+                                                 ? high - 1 - low : low));
              m_first = false;
              m_data[save_data_cnt + 2]
                = build_int_cst (NULL_TREE, m_data_cnt);
@@ -1389,6 +1458,18 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
          if (m_upwards_2limb
              && low >= m_upwards_2limb - m_first)
            {
+             if (bitint_big_endian
+                 && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
+                     != CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
+               {
+                 HOST_WIDE_INT diff
+                   = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
+                 diff -= CEIL (TYPE_PRECISION (lhs_type), limb_prec);
+                 tree t = make_ssa_name (sizetype);
+                 g = gimple_build_assign (t, PLUS_EXPR, idx, size_int (diff));
+                 insert_before (g);
+                 idx = t;
+               }
              rhs1 = handle_operand (rhs1, idx);
              if (m_first)
                m_data[save_data_cnt + 2]
@@ -1410,13 +1491,18 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
               emits.  So, instead of special-casing that, emit a
               low <= low comparison which cfg cleanup will clean up
               at the end of the pass.  */
-           idxc = size_int (low);
-         g = gimple_build_cond (single_comparison ? LT_EXPR : LE_EXPR,
-                                idxc, size_int (low), NULL_TREE, NULL_TREE);
+           idxc = size_int (lowe);
+         if (bitint_big_endian)
+           g = gimple_build_cond (single_comparison ? GT_EXPR : GE_EXPR,
+                                  idxc, size_int (lowe),
+                                  NULL_TREE, NULL_TREE);
+         else
+           g = gimple_build_cond (single_comparison ? LT_EXPR : LE_EXPR,
+                                  idxc, size_int (low), NULL_TREE, NULL_TREE);
          edge edge_true_true, edge_true_false, edge_false;
          if_then_if_then_else (g, (single_comparison ? NULL
                                    : gimple_build_cond (EQ_EXPR, idx,
-                                                        size_int (low),
+                                                        size_int (lowe),
                                                         NULL_TREE,
                                                         NULL_TREE)),
                                profile_probability::likely (),
@@ -1425,7 +1511,18 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
          bool save_cast_conditional = m_cast_conditional;
          m_cast_conditional = true;
          m_bitfld_load = 0;
-         tree t1 = handle_operand (rhs1, idx), t2 = NULL_TREE;
+         tree t1 = idx, t2 = NULL_TREE;
+         if (bitint_big_endian
+             && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
+                 != CEIL (TYPE_PRECISION (rhs_type), limb_prec)))
+           {
+             HOST_WIDE_INT diff = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
+             diff -= CEIL (TYPE_PRECISION (lhs_type), limb_prec);
+             t1 = make_ssa_name (sizetype);
+             g = gimple_build_assign (t1, PLUS_EXPR, idx, size_int (diff));
+             insert_before (g);
+           }
+         t1 = handle_operand (rhs1, t1);
          if (m_first)
            m_data[save_data_cnt + 2]
              = build_int_cst (NULL_TREE, m_data_cnt);
@@ -1442,7 +1539,8 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
                  m_data[m_bitfld_load] = m_data[m_bitfld_load + 2];
                  m_bitfld_load = 0;
                }
-             t2 = handle_operand (rhs1, size_int (low));
+             t2 = handle_operand (rhs1, size_int (bitint_big_endian
+                                                  ? high - 1 - low : low));
              if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (t2)))
                t2 = add_cast (m_limb_type, t2);
              if (!TYPE_UNSIGNED (rhs_type) && m_upwards_2limb)
@@ -1548,16 +1646,20 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
       else
        {
          unsigned tidx = tree_to_uhwi (idx);
+         if (bitint_big_endian)
+           tidx = lcnt - 1 - tidx;
          if (tidx < low)
            {
-             t = handle_operand (rhs1, idx);
+             t = handle_operand (rhs1, (bitint_big_endian
+                                        ? size_int (high - 1 - tidx) : idx));
              if (m_first)
                m_data[save_data_cnt + 2]
                  = build_int_cst (NULL_TREE, m_data_cnt);
            }
          else if (tidx < high)
            {
-             t = handle_operand (rhs1, size_int (low));
+             t = handle_operand (rhs1, size_int (bitint_big_endian
+                                                 ? high - 1 - low : low));
              if (m_first)
                m_data[save_data_cnt + 2]
                  = build_int_cst (NULL_TREE, m_data_cnt);
@@ -1580,7 +1682,9 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
            {
              if (TYPE_UNSIGNED (rhs_type) && m_first)
                {
-                 handle_operand (rhs1, size_zero_node);
+                 handle_operand (rhs1, (bitint_big_endian
+                                        ? size_int (high - 1)
+                                        : size_zero_node));
                  m_data[save_data_cnt + 2]
                    = build_int_cst (NULL_TREE, m_data_cnt);
                }
@@ -1695,13 +1799,17 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
          m_data.safe_push (r2);
          m_data.safe_push (rext);
        }
+      unsigned lcnt = CEIL ((unsigned) TYPE_PRECISION (lhs_type), limb_prec);
       if (tree_fits_uhwi_p (idx))
        {
          tree type = limb_access_type (lhs_type, idx);
-         if (integer_zerop (idx))
+         if (bitint_big_endian
+             ? tree_to_uhwi (idx) == lcnt - 1 : integer_zerop (idx))
            t = m_data[m_data_cnt];
          else if (TYPE_PRECISION (rhs_type) > limb_prec
-                  && integer_onep (idx))
+                  && (bitint_big_endian
+                      ? tree_to_uhwi (idx) == lcnt - 2
+                      : integer_onep (idx)))
            t = m_data[m_data_cnt + 1];
          else
            t = m_data[m_data_cnt + 2];
@@ -1710,13 +1818,17 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
          m_data_cnt += 3;
          return t;
        }
-      g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
+      g = gimple_build_cond (NE_EXPR, idx,
+                            bitint_big_endian
+                            ? size_int (lcnt - 1) : size_zero_node,
                             NULL_TREE, NULL_TREE);
       edge e2, e3, e4 = NULL;
       if_then (g, profile_probability::likely (), e2, e3);
       if (m_data[m_data_cnt + 1])
        {
-         g = gimple_build_cond (EQ_EXPR, idx, size_one_node,
+         g = gimple_build_cond (EQ_EXPR, idx,
+                                bitint_big_endian
+                                ? size_int (lcnt - 2) : size_one_node,
                                 NULL_TREE, NULL_TREE);
          insert_before (g);
          edge e5 = split_block (gsi_bb (m_gsi), g);
@@ -1750,11 +1862,14 @@ bitint_large_huge::handle_bit_field_ref (tree op, tree idx)
        m_data.safe_push (NULL);
       ++m_data_cnt;
       unsigned HOST_WIDE_INT sz = tree_to_uhwi (TYPE_SIZE (m_limb_type));
+      unsigned i = tree_to_uhwi (idx);
+      if (bitint_big_endian)
+       i = CEIL (TYPE_PRECISION (TREE_TYPE (op)), limb_prec) - 1 - i;
       tree bfr = build3 (BIT_FIELD_REF, m_limb_type,
                         TREE_OPERAND (op, 0),
                         TYPE_SIZE (m_limb_type),
                         size_binop (PLUS_EXPR, TREE_OPERAND (op, 2),
-                                    bitsize_int (tree_to_uhwi (idx) * sz)));
+                                    bitsize_int (i * sz)));
       tree r = make_ssa_name (m_limb_type);
       gimple *g = gimple_build_assign (r, bfr);
       insert_before (g);
@@ -1868,12 +1983,14 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
       /* For little-endian, we can allow as inputs bit-fields
         which start at a limb boundary.  */
       gcc_assert (tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fld)));
-      if (DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1))
+      if (!bitint_big_endian
+         && DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1))
          && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % limb_prec) == 0)
        goto normal_load;
-      /* Even if DECL_FIELD_BIT_OFFSET (fld) is a multiple of UNITS_PER_BIT,
+      /* Even if DECL_FIELD_BIT_OFFSET (fld) is a multiple of BITS_PER_UNIT,
         handle it normally for now.  */
-      if ((tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % BITS_PER_UNIT) == 0)
+      if (!bitint_big_endian
+         && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % BITS_PER_UNIT) == 0)
        goto normal_load;
       tree repr = DECL_BIT_FIELD_REPRESENTATIVE (fld);
       poly_int64 bitoffset;
@@ -1895,9 +2012,19 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
       HOST_WIDE_INT bo = bitoffset.to_constant ();
       unsigned bo_idx = (unsigned HOST_WIDE_INT) bo / limb_prec;
       unsigned bo_bit = (unsigned HOST_WIDE_INT) bo % limb_prec;
+      unsigned bo_last = 0;
+      unsigned bo_shift = bo_bit;
+      unsigned nelts = CEIL (TYPE_PRECISION (rhs_type), limb_prec);
+      if (bitint_big_endian)
+       {
+         bo_last = CEIL (TYPE_PRECISION (rhs_type) + bo_bit, limb_prec) - 1;
+         bo_shift = (TYPE_PRECISION (rhs_type) + bo_bit) % limb_prec;
+         if (bo_shift)
+           bo_shift = limb_prec - bo_shift;
+       }
       if (m_first)
        {
-         if (m_upwards)
+         if (m_upwards && bo_shift)
            {
              gimple_stmt_iterator save_gsi = m_gsi;
              m_gsi = m_init_gsi;
@@ -1905,7 +2032,8 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
                m_gsi = gsi_after_labels (gsi_bb (m_gsi));
              else
                gsi_next (&m_gsi);
-             tree t = limb_access (NULL_TREE, nrhs1, size_int (bo_idx), true);
+             tree t = limb_access (NULL_TREE, nrhs1,
+                                   size_int (bo_idx + bo_last), true);
              tree iv = make_ssa_name (m_limb_type);
              g = gimple_build_assign (iv, t);
              insert_before (g);
@@ -1947,7 +2075,7 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
            }
        }
 
-      tree nidx0 = NULL_TREE, nidx1;
+      tree nidx0 = NULL_TREE, nidx1 = NULL_TREE;
       tree iv = m_data[m_data_cnt];
       if (m_cast_conditional && iv)
        {
@@ -1958,8 +2086,12 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
        {
          unsigned prec = TYPE_PRECISION (rhs_type);
          unsigned HOST_WIDE_INT i = tree_to_uhwi (idx);
+         if (bitint_big_endian)
+           i = nelts - 1 - i;
          gcc_assert (i * limb_prec < prec);
-         nidx1 = size_int (i + bo_idx + 1);
+         if (bo_shift)
+           nidx1 = size_int (bo_idx + (bitint_big_endian
+                                       ? bo_last - i - 1 : i + 1));
          if ((i + 1) * limb_prec > prec)
            {
              prec %= limb_prec;
@@ -1967,26 +2099,38 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
                nidx1 = NULL_TREE;
            }
          if (!iv)
-           nidx0 = size_int (i + bo_idx);
+           nidx0 = size_int (bo_idx + (bitint_big_endian ? bo_last - i : i));
        }
       else
        {
+         HOST_WIDE_INT adj = bo_idx;
+         if (bitint_big_endian)
+           adj += (HOST_WIDE_INT) bo_last + 1 - nelts;
          if (!iv)
            {
-             if (bo_idx == 0)
+             if (adj == 0)
                nidx0 = idx;
              else
                {
                  nidx0 = make_ssa_name (sizetype);
                  g = gimple_build_assign (nidx0, PLUS_EXPR, idx,
-                                          size_int (bo_idx));
+                                          size_int (adj));
+                 insert_before (g);
+               }
+           }
+         if (bo_shift)
+           {
+             if (bitint_big_endian && adj == 1)
+               nidx1 = idx;
+             else
+               {
+                 nidx1 = make_ssa_name (sizetype);
+                 g = gimple_build_assign (nidx1, PLUS_EXPR, idx,
+                                          size_int (adj + (bitint_big_endian
+                                                           ? -1 : 1)));
                  insert_before (g);
                }
            }
-         nidx1 = make_ssa_name (sizetype);
-         g = gimple_build_assign (nidx1, PLUS_EXPR, idx,
-                                  size_int (bo_idx + 1));
-         insert_before (g);
        }
 
       tree iv2 = NULL_TREE;
@@ -1996,7 +2140,16 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
          iv = make_ssa_name (m_limb_type);
          g = gimple_build_assign (iv, t);
          insert_before (g);
-         gcc_assert (!eh);
+         if (eh)
+           {
+             maybe_duplicate_eh_stmt (g, stmt);
+             if (eh_edge)
+               {
+                 edge e = split_block (gsi_bb (m_gsi), g);
+                 m_gsi = gsi_after_labels (e->dest);
+                 add_eh_edge (e->src, eh_edge);
+               }
+           }
        }
       if (nidx1)
        {
@@ -2012,7 +2165,9 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
          if (conditional)
            {
              g = gimple_build_cond (NE_EXPR, idx,
-                                    size_int (prec / limb_prec),
+                                    bitint_big_endian
+                                    ? size_zero_node
+                                    : size_int (prec / limb_prec),
                                     NULL_TREE, NULL_TREE);
              if_then (g, profile_probability::likely (),
                       edge_true, edge_false);
@@ -2050,15 +2205,19 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx)
              iv2 = iv3;
            }
        }
-      g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
-                              iv, build_int_cst (unsigned_type_node, bo_bit));
-      insert_before (g);
-      iv = gimple_assign_lhs (g);
+      if (bo_shift)
+       {
+         g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
+                                  iv, build_int_cst (unsigned_type_node,
+                                                     bo_shift));
+         insert_before (g);
+         iv = gimple_assign_lhs (g);
+       }
       if (iv2)
        {
          g = gimple_build_assign (make_ssa_name (m_limb_type), LSHIFT_EXPR,
                                   iv2, build_int_cst (unsigned_type_node,
-                                                      limb_prec - bo_bit));
+                                                      limb_prec - bo_shift));
          insert_before (g);
          g = gimple_build_assign (make_ssa_name (m_limb_type), BIT_IOR_EXPR,
                                   gimple_assign_lhs (g), iv);
@@ -2221,6 +2380,8 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
 {
   wide_int w;
   location_t loc_save = m_loc;
+  tree ret = NULL_TREE;
+  int precs = 0;
   if ((TREE_CODE (TREE_TYPE (op)) != BITINT_TYPE
        || bitint_precision_kind (TREE_TYPE (op)) < bitint_prec_large)
       && TREE_CODE (op) != INTEGER_CST)
@@ -2244,30 +2405,29 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
         limb mode smaller than half of largest supported normal
         integral type, this will not be needed.  */
       gcc_assert (nelts <= 2);
-      if (prec_stored)
-       *prec_stored = (TYPE_UNSIGNED (op_type)
-                       ? TYPE_PRECISION (op_type)
-                       : -TYPE_PRECISION (op_type));
+      precs = (TYPE_UNSIGNED (op_type)
+              ? TYPE_PRECISION (op_type) : -TYPE_PRECISION (op_type));
       if (*prec <= limb_prec && *prec >= -limb_prec)
        {
          nelts = 1;
-         if (prec_stored)
+         if (TYPE_UNSIGNED (op_type))
            {
-             if (TYPE_UNSIGNED (op_type))
-               {
-                 if (*prec_stored > limb_prec)
-                   *prec_stored = limb_prec;
-               }
-             else if (*prec_stored < -limb_prec)
-               *prec_stored = -limb_prec;
+             if (precs > limb_prec)
+               precs = limb_prec;
            }
+         else if (precs < -limb_prec)
+           precs = -limb_prec;
        }
+      if (prec_stored)
+       *prec_stored = precs;
       tree atype = build_array_type_nelts (m_limb_type, nelts);
       tree var = create_tmp_var (atype);
       tree t1 = op;
       if (!useless_type_conversion_p (m_limb_type, op_type))
        t1 = add_cast (m_limb_type, t1);
-      tree v = build4 (ARRAY_REF, m_limb_type, var, size_zero_node,
+      tree v = build4 (ARRAY_REF, m_limb_type, var,
+                      bitint_big_endian && nelts > 1
+                      ? size_one_node : size_zero_node,
                       NULL_TREE, NULL_TREE);
       gimple *g = gimple_build_assign (v, t1);
       insert_before (g);
@@ -2279,12 +2439,13 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
          insert_before (g);
          tree t2 = gimple_assign_lhs (g);
          t2 = add_cast (m_limb_type, t2);
-         v = build4 (ARRAY_REF, m_limb_type, var, size_one_node,
+         v = build4 (ARRAY_REF, m_limb_type, var,
+                     bitint_big_endian ? size_zero_node : size_one_node,
                      NULL_TREE, NULL_TREE);
          g = gimple_build_assign (v, t2);
          insert_before (g);
        }
-      tree ret = build_fold_addr_expr (var);
+      ret = build_fold_addr_expr (var);
       if (!stmt_ends_bb_p (gsi_stmt (m_gsi)))
        {
          tree clobber = build_clobber (atype, CLOBBER_STORAGE_END);
@@ -2292,7 +2453,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
          gsi_insert_after (&m_gsi, g, GSI_SAME_STMT);
        }
       m_loc = loc_save;
-      return ret;
+      goto do_ret;
     }
   switch (TREE_CODE (op))
     {
@@ -2301,15 +2462,15 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
          || !bitmap_bit_p (m_names, SSA_NAME_VERSION (op)))
        {
          gimple *g = SSA_NAME_DEF_STMT (op);
-         tree ret;
          m_loc = gimple_location (g);
          if (gimple_assign_load_p (g))
            {
              *prec = range_to_prec (op, NULL);
+             precs = (TYPE_UNSIGNED (TREE_TYPE (op))
+                      ? TYPE_PRECISION (TREE_TYPE (op))
+                      : -TYPE_PRECISION (TREE_TYPE (op)));
              if (prec_stored)
-               *prec_stored = (TYPE_UNSIGNED (TREE_TYPE (op))
-                               ? TYPE_PRECISION (TREE_TYPE (op))
-                               : -TYPE_PRECISION (TREE_TYPE (op)));
+               *prec_stored = precs;
              ret = build_fold_addr_expr (gimple_assign_rhs1 (g));
              ret = force_gimple_operand_gsi (&m_gsi, ret, true,
                                              NULL_TREE, true, GSI_SAME_STMT);
@@ -2317,8 +2478,9 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
          else if (gimple_code (g) == GIMPLE_NOP)
            {
              *prec = TYPE_UNSIGNED (TREE_TYPE (op)) ? limb_prec : -limb_prec;
+             precs = *prec;
              if (prec_stored)
-               *prec_stored = *prec;
+               *prec_stored = precs;
              tree var = create_tmp_var (m_limb_type);
              TREE_ADDRESSABLE (var) = 1;
              ret = build_fold_addr_expr (var);
@@ -2346,6 +2508,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
                  tree rhs_type = TREE_TYPE (rhs1);
                  int prec_stored_val = 0;
                  ret = handle_operand_addr (rhs1, g, &prec_stored_val, prec);
+                 precs = prec_stored_val;
                  if (TYPE_PRECISION (lhs_type) > TYPE_PRECISION (rhs_type))
                    {
                      if (TYPE_UNSIGNED (lhs_type)
@@ -2378,18 +2541,20 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
                }
            }
          m_loc = loc_save;
-         return ret;
+         goto do_ret;
        }
       else
        {
          int p = var_to_partition (m_map, op);
          gcc_assert (m_vars[p] != NULL_TREE);
          *prec = range_to_prec (op, stmt);
+         precs = (TYPE_UNSIGNED (TREE_TYPE (op))
+                  ? TYPE_PRECISION (TREE_TYPE (op))
+                  : -TYPE_PRECISION (TREE_TYPE (op)));
          if (prec_stored)
-           *prec_stored = (TYPE_UNSIGNED (TREE_TYPE (op))
-                           ? TYPE_PRECISION (TREE_TYPE (op))
-                           : -TYPE_PRECISION (TREE_TYPE (op)));
-         return build_fold_addr_expr (m_vars[p]);
+           *prec_stored = precs;
+         ret = build_fold_addr_expr (m_vars[p]);
+         goto do_ret;
        }
     case INTEGER_CST:
       unsigned int min_prec, mp;
@@ -2430,18 +2595,37 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt,
              type = build_bitint_type (mp, 1);
            }
        }
+      if (tree_int_cst_sgn (op) >= 0)
+       precs = MAX (TYPE_PRECISION (type), 1);
+      else
+       precs = MIN ((int) -TYPE_PRECISION (type), -2);
       if (prec_stored)
-       {
-         if (tree_int_cst_sgn (op) >= 0)
-           *prec_stored = MAX (TYPE_PRECISION (type), 1);
-         else
-           *prec_stored = MIN ((int) -TYPE_PRECISION (type), -2);
-       }
+       *prec_stored = precs;
       op = tree_output_constant_def (fold_convert (type, op));
-      return build_fold_addr_expr (op);
+      ret = build_fold_addr_expr (op);
+      goto do_ret;
     default:
       gcc_unreachable ();
     }
+do_ret:
+  if (bitint_big_endian && prec_stored == NULL)
+    {
+      int p1 = *prec < 0 ? -*prec : *prec;
+      int p2 = precs < 0 ? -precs : precs;
+      int c1 = CEIL (p1, limb_prec);
+      int c2 = CEIL (p2, limb_prec);
+      gcc_assert (c1 <= c2);
+      if (c1 != c2)
+       {
+         gimple *g
+           = gimple_build_assign (make_ssa_name (TREE_TYPE (ret)),
+                                  POINTER_PLUS_EXPR, ret,
+                                  size_int ((c2 - c1) * m_limb_size));
+         insert_before (g);
+         ret = gimple_assign_lhs (g);
+       }
+    }
+  return ret;
 }
 
 /* Helper function, create a loop before the current location,
@@ -2518,6 +2702,9 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
   tree nlhs = NULL_TREE;
   unsigned HOST_WIDE_INT bo_idx = 0;
   unsigned HOST_WIDE_INT bo_bit = 0;
+  unsigned bo_shift = 0;
+  unsigned bo_last = 0;
+  bool bo_be_p = false;
   tree bf_cur = NULL_TREE, bf_next = NULL_TREE;
   if (gimple_store_p (stmt))
     {
@@ -2544,7 +2731,9 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
          tree repr = DECL_BIT_FIELD_REPRESENTATIVE (fld);
          poly_int64 bitoffset;
          poly_uint64 field_offset, repr_offset;
-         if ((tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % BITS_PER_UNIT) == 0)
+         if (!bitint_big_endian
+             && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld))
+                 % BITS_PER_UNIT) == 0)
            nlhs = lhs;
          else
            {
@@ -2566,6 +2755,15 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
              HOST_WIDE_INT bo = bitoffset.to_constant ();
              bo_idx = (unsigned HOST_WIDE_INT) bo / limb_prec;
              bo_bit = (unsigned HOST_WIDE_INT) bo % limb_prec;
+             bo_shift = bo_bit;
+             if (bitint_big_endian)
+               {
+                 bo_last = CEIL (prec + bo_bit, limb_prec) - 1;
+                 bo_shift = (prec + bo_bit) % limb_prec;
+                 bo_be_p = true;
+                 if (bo_shift)
+                   bo_shift = limb_prec - bo_shift;
+               }
            }
        }
     }
@@ -2609,7 +2807,9 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
       rem = (prec % (2 * limb_prec));
       end = (prec - rem) / limb_prec;
       cnt = 2 + CEIL (rem, limb_prec);
-      idx = idx_first = create_loop (size_zero_node, &idx_next);
+      idx = idx_first = create_loop (bitint_big_endian
+                                    ? size_int (cnt - 2 + end - 1)
+                                    : size_zero_node, &idx_next);
     }
 
   basic_block edge_bb = NULL;
@@ -2632,14 +2832,18 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
     = (prec != (unsigned) TYPE_PRECISION (type)
        && (CEIL ((unsigned) TYPE_PRECISION (type), limb_prec)
           > CEIL (prec, limb_prec)));
+  unsigned dst_idx_off = 0;
+  if (separate_ext && bitint_big_endian)
+    dst_idx_off = (CEIL ((unsigned) TYPE_PRECISION (type), limb_prec)
+                  - CEIL (prec, limb_prec));
 
   for (unsigned i = 0; i < cnt; i++)
     {
       m_data_cnt = 0;
       if (kind == bitint_prec_large)
-       idx = size_int (i);
+       idx = size_int (bitint_big_endian ? cnt - 1 - i : i);
       else if (i >= 2)
-       idx = size_int (end + (i > 2));
+       idx = size_int (bitint_big_endian ? cnt - 1 - i : end + (i > 2));
       if (eq_p)
        {
          rhs1 = handle_operand (cmp_op1, idx);
@@ -2666,22 +2870,27 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
          if (sext && i == cnt - 1)
            ext = rhs1;
          tree nidx = idx;
-         if (bo_idx)
+         HOST_WIDE_INT adj = bo_idx;
+         if (bo_be_p)
+           adj += bo_last - (CEIL (prec, limb_prec) - 1);
+         else
+           adj += dst_idx_off;
+         if (adj)
            {
              if (tree_fits_uhwi_p (idx))
-               nidx = size_int (tree_to_uhwi (idx) + bo_idx);
+               nidx = size_int (tree_to_uhwi (idx) + adj);
              else
                {
                  nidx = make_ssa_name (sizetype);
                  g = gimple_build_assign (nidx, PLUS_EXPR, idx,
-                                          size_int (bo_idx));
+                                          size_int (adj));
                  insert_before (g);
                }
            }
          bool done = false;
          basic_block new_bb = NULL;
          /* Handle stores into bit-fields.  */
-         if (bo_bit)
+         if (bo_shift)
            {
              if (i == 0)
                {
@@ -2692,7 +2901,11 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
                                           idx, &bf_next);
                      bf_next = m_data.pop ();
                      bf_cur = m_data.pop ();
-                     g = gimple_build_cond (EQ_EXPR, idx, size_zero_node,
+                     g = gimple_build_cond (EQ_EXPR, idx,
+                                            bitint_big_endian
+                                            ? size_int (CEIL (prec,
+                                                              limb_prec) - 1)
+                                            : size_zero_node,
                                             NULL_TREE, NULL_TREE);
                      edge edge_true;
                      if_then_else (g, profile_probability::unlikely (),
@@ -2700,10 +2913,14 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
                      new_bb = e2->dest;
                    }
                  tree ftype
-                   = build_nonstandard_integer_type (limb_prec - bo_bit, 1);
+                   = build_nonstandard_integer_type (limb_prec - bo_shift, 1);
                  tree bfr = build_bit_field_ref (ftype, unshare_expr (nlhs),
-                                                 limb_prec - bo_bit,
-                                                 bo_idx * limb_prec + bo_bit);
+                                                 limb_prec - bo_shift,
+                                                 bitint_big_endian
+                                                 ? (bo_idx + bo_last)
+                                                   * limb_prec
+                                                 : bo_idx * limb_prec
+                                                   + bo_bit);
                  tree t = add_cast (ftype, rhs1);
                  g = gimple_build_assign (bfr, t);
                  insert_before (g);
@@ -2733,11 +2950,12 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
                  tree t3 = make_ssa_name (m_limb_type);
                  g = gimple_build_assign (t1, RSHIFT_EXPR, bf_cur,
                                           build_int_cst (unsigned_type_node,
-                                                         limb_prec - bo_bit));
+                                                         limb_prec
+                                                         - bo_shift));
                  insert_before (g);
                  g = gimple_build_assign (t2, LSHIFT_EXPR, rhs1,
                                           build_int_cst (unsigned_type_node,
-                                                         bo_bit));
+                                                         bo_shift));
                  insert_before (g);
                  bf_cur = rhs1;
                  g = gimple_build_assign (t3, BIT_IOR_EXPR, t1, t2);
@@ -2760,21 +2978,23 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
                {
                  unsigned int tprec = TYPE_PRECISION (type);
                  unsigned int rprec = (tprec - 1) % limb_prec + 1;
-                 if (rprec + bo_bit < (unsigned) limb_prec)
+                 if (rprec + bo_shift < (unsigned) limb_prec)
                    {
                      tree ftype
-                       = build_nonstandard_integer_type (rprec + bo_bit, 1);
+                       = build_nonstandard_integer_type (rprec + bo_shift, 1);
                      tree bfr
                        = build_bit_field_ref (ftype, unshare_expr (nlhs),
-                                              rprec + bo_bit,
-                                              (bo_idx + tprec / limb_prec)
-                                              * limb_prec);
+                                              rprec + bo_shift,
+                                              bitint_big_endian
+                                              ? bo_idx * limb_prec + bo_bit
+                                              : (bo_idx + tprec / limb_prec)
+                                                * limb_prec);
                      tree t = add_cast (ftype, rhs1);
                      g = gimple_build_assign (bfr, t);
                      done = true;
                      bf_cur = NULL_TREE;
                    }
-                 else if (rprec + bo_bit == (unsigned) limb_prec)
+                 else if (rprec + bo_shift == (unsigned) limb_prec)
                    bf_cur = NULL_TREE;
                }
              /* Otherwise, stores to any other lhs.  */
@@ -2807,16 +3027,21 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
            {
              idx = make_ssa_name (sizetype);
              g = gimple_build_assign (idx, PLUS_EXPR, idx_first,
-                                      size_one_node);
+                                      bitint_big_endian
+                                      ? size_int (-1) : size_one_node);
              insert_before (g);
            }
          else
            {
              g = gimple_build_assign (idx_next, PLUS_EXPR, idx_first,
-                                      size_int (2));
+                                      size_int (bitint_big_endian ? -2 : 2));
              insert_before (g);
-             g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
-                                    NULL_TREE, NULL_TREE);
+             if (bitint_big_endian)
+               g = gimple_build_cond (NE_EXPR, idx_first, size_int (cnt - 1),
+                                      NULL_TREE, NULL_TREE);
+             else
+               g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
+                                      NULL_TREE, NULL_TREE);
              insert_before (g);
              if (eq_p)
                m_gsi = gsi_after_labels (edge_bb);
@@ -2844,32 +3069,40 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
       kind = bitint_precision_kind (type);
       unsigned start = CEIL (prec, limb_prec);
       prec = TYPE_PRECISION (type);
+      unsigned total = CEIL (prec, limb_prec);
       idx = idx_first = idx_next = NULL_TREE;
-      if (prec <= (start + 2 + (bo_bit != 0)) * limb_prec)
+      if (prec <= (start + 2 + (bo_shift != 0)) * limb_prec)
        kind = bitint_prec_large;
       if (kind == bitint_prec_large)
-       cnt = CEIL (prec, limb_prec) - start;
+       cnt = total - start;
       else
        {
          rem = prec % limb_prec;
          end = (prec - rem) / limb_prec;
-         cnt = (bo_bit != 0) + 1 + (rem != 0);
+         cnt = (bo_shift != 0) + 1 + (rem != 0);
        }
+      if (bitint_big_endian && bo_shift != 0 && (prec % limb_prec) == 0)
+       ++total;
       for (unsigned i = 0; i < cnt; i++)
        {
-         if (kind == bitint_prec_large || (i == 0 && bo_bit != 0))
-           idx = size_int (start + i);
-         else if (i == cnt - 1 && (rem != 0))
-           idx = size_int (end);
-         else if (i == (bo_bit != 0))
-           idx = create_loop (size_int (start + i), &idx_next);
+         if (kind == bitint_prec_large || (i == 0 && bo_shift != 0))
+           idx = size_int (bo_idx
+                           + (bitint_big_endian
+                              ? total - 1 - start - i : start + i));
+         else if (i == cnt - 1 && rem != 0)
+           idx = size_int (bo_idx + (bitint_big_endian ? 0 : end));
+         else if (i == (bo_shift != 0))
+           idx = create_loop (size_int (bo_idx
+                                        + (bitint_big_endian
+                                           ? total - 1 - start - i
+                                           : start + i)), &idx_next);
          rhs1 = ext;
          if (bf_cur != NULL_TREE && bf_cur != ext)
            {
              tree t1 = make_ssa_name (m_limb_type);
              g = gimple_build_assign (t1, RSHIFT_EXPR, bf_cur,
                                       build_int_cst (unsigned_type_node,
-                                                     limb_prec - bo_bit));
+                                                     limb_prec - bo_shift));
              insert_before (g);
              if (integer_zerop (ext))
                rhs1 = t1;
@@ -2879,54 +3112,43 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
                  rhs1 = make_ssa_name (m_limb_type);
                  g = gimple_build_assign (t2, LSHIFT_EXPR, ext,
                                           build_int_cst (unsigned_type_node,
-                                                         bo_bit));
+                                                         bo_shift));
                  insert_before (g);
                  g = gimple_build_assign (rhs1, BIT_IOR_EXPR, t1, t2);
                  insert_before (g);
                }
              bf_cur = ext;
            }
-         tree nidx = idx;
-         if (bo_idx)
-           {
-             if (tree_fits_uhwi_p (idx))
-               nidx = size_int (tree_to_uhwi (idx) + bo_idx);
-             else
-               {
-                 nidx = make_ssa_name (sizetype);
-                 g = gimple_build_assign (nidx, PLUS_EXPR, idx,
-                                          size_int (bo_idx));
-                 insert_before (g);
-               }
-           }
          bool done = false;
          /* Handle bit-field access to partial last limb if needed.  */
          if (nlhs && i == cnt - 1)
            {
              unsigned int tprec = TYPE_PRECISION (type);
              unsigned int rprec = (tprec - 1) % limb_prec + 1;
-             if (rprec + bo_bit < (unsigned) limb_prec)
+             if (rprec + bo_shift < (unsigned) limb_prec)
                {
                  tree ftype
-                   = build_nonstandard_integer_type (rprec + bo_bit, 1);
+                   = build_nonstandard_integer_type (rprec + bo_shift, 1);
                  tree bfr
                    = build_bit_field_ref (ftype, unshare_expr (nlhs),
-                                          rprec + bo_bit,
-                                          (bo_idx + tprec / limb_prec)
-                                          * limb_prec);
+                                          rprec + bo_shift,
+                                          bitint_big_endian
+                                          ? bo_idx * limb_prec + bo_bit
+                                          : (bo_idx + tprec / limb_prec)
+                                            * limb_prec);
                  tree t = add_cast (ftype, rhs1);
                  g = gimple_build_assign (bfr, t);
                  done = true;
                  bf_cur = NULL_TREE;
                }
-             else if (rprec + bo_bit == (unsigned) limb_prec)
+             else if (rprec + bo_shift == (unsigned) limb_prec)
                bf_cur = NULL_TREE;
            }
          /* Otherwise, stores to any other lhs.  */
          if (!done)
            {
              tree l = limb_access (nlhs ? NULL_TREE : lhs_type,
-                                   nlhs ? nlhs : lhs, nidx, true);
+                                   nlhs ? nlhs : lhs, idx, true);
              g = gimple_build_assign (l, rhs1);
            }
          insert_before (g);
@@ -2940,13 +3162,22 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
                  add_eh_edge (e->src, find_edge (gimple_bb (stmt), eh_pad));
                }
            }
-         if (kind == bitint_prec_huge && i == (bo_bit != 0))
+         if (kind == bitint_prec_huge && i == (bo_shift != 0))
            {
              g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
-                                      size_one_node);
+                                      bitint_big_endian
+                                      ? size_int (-1) : size_one_node);
              insert_before (g);
-             g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
-                                    NULL_TREE, NULL_TREE);
+             if (bitint_big_endian && rem != 0)
+               g = gimple_build_cond (NE_EXPR, idx,
+                                      size_int (bo_idx + 1),
+                                      NULL_TREE, NULL_TREE);
+             else
+               g = gimple_build_cond (NE_EXPR, idx_next,
+                                      size_int (bo_idx
+                                                + (bitint_big_endian
+                                                   ? 0 : end)),
+                                      NULL_TREE, NULL_TREE);
              insert_before (g);
              m_gsi = gsi_for_stmt (stmt);
              m_bb = NULL;
@@ -2956,19 +3187,21 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
   if (bf_cur != NULL_TREE)
     {
       unsigned int tprec = TYPE_PRECISION (type);
-      unsigned int rprec = (tprec + bo_bit) % limb_prec;
+      unsigned int rprec = (tprec + bo_shift) % limb_prec;
       tree ftype = build_nonstandard_integer_type (rprec, 1);
       tree bfr = build_bit_field_ref (ftype, unshare_expr (nlhs),
                                      rprec,
-                                     (bo_idx + (tprec + bo_bit) / limb_prec)
-                                     * limb_prec);
+                                     bitint_big_endian
+                                     ? bo_idx * limb_prec + bo_bit
+                                     : (bo_idx + (tprec + bo_bit) / limb_prec)
+                                       * limb_prec);
       rhs1 = bf_cur;
       if (bf_cur != ext)
        {
          rhs1 = make_ssa_name (TREE_TYPE (rhs1));
          g = gimple_build_assign (rhs1, RSHIFT_EXPR, bf_cur,
                                   build_int_cst (unsigned_type_node,
-                                                 limb_prec - bo_bit));
+                                                 limb_prec - bo_shift));
          insert_before (g);
        }
       rhs1 = add_cast (ftype, rhs1);
@@ -3039,7 +3272,7 @@ bitint_large_huge::lower_comparison_stmt (gimple *stmt, tree_code &cmp_code,
       && (cmp_code == GE_EXPR || cmp_code == LT_EXPR))
     {
       unsigned end = CEIL ((unsigned) TYPE_PRECISION (type), limb_prec) - 1;
-      tree idx = size_int (end);
+      tree idx = size_int (bitint_big_endian ? 0 : end);
       m_data_cnt = 0;
       tree rhs1 = handle_operand (cmp_op1, idx);
       if (TYPE_UNSIGNED (TREE_TYPE (rhs1)))
@@ -3080,11 +3313,12 @@ bitint_large_huge::lower_comparison_stmt (gimple *stmt, tree_code &cmp_code,
     {
       m_data_cnt = 0;
       if (kind == bitint_prec_large)
-       idx = size_int (cnt - i - 1);
+       idx = size_int (bitint_big_endian ? i : cnt - i - 1);
       else if (i == cnt - 1)
-       idx = create_loop (size_int (end - 1), &idx_next);
+       idx = create_loop (size_int (bitint_big_endian ? cnt - 1 : end - 1),
+                          &idx_next);
       else
-       idx = size_int (end);
+       idx = size_int (bitint_big_endian ? 0 : end);
       tree rhs1 = handle_operand (cmp_op1, idx);
       tree rhs2 = handle_operand (cmp_op2, idx);
       if (i == 0
@@ -3118,9 +3352,14 @@ bitint_large_huge::lower_comparison_stmt (gimple *stmt, tree_code &cmp_code,
       m_first = false;
       if (kind == bitint_prec_huge && i == cnt - 1)
        {
-         g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_int (-1));
+         g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                                  bitint_big_endian ? size_one_node
+                                  : size_int (-1));
          insert_before (g);
-         g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
+         g = gimple_build_cond (NE_EXPR, idx,
+                                bitint_big_endian
+                                ? size_int (end - 1 + (cnt != 1))
+                                : size_zero_node,
                                 NULL_TREE, NULL_TREE);
          insert_before (g);
          edge true_edge, false_edge;
@@ -3174,7 +3413,7 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
      size_t n2 = n / limb_prec;
      size_t n3 = n1 != 0;
      unsigned n4 = (limb_prec - n1) % limb_prec;
-     (for power of 2 limb_prec n4 can be -n1 & (limb_prec)).  */
+     (for power of 2 limb_prec n4 can be -n1 & limb_prec).  */
   if (TREE_CODE (n) == INTEGER_CST)
     {
       tree lp = build_int_cst (TREE_TYPE (n), limb_prec);
@@ -3290,7 +3529,9 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
             dst[idx] = ext;  */
       tree pmn3;
       if (TYPE_UNSIGNED (type) && prec % limb_prec == 0)
-       pmn3 = p;
+       pmn3 = bitint_big_endian ? size_zero_node : p;
+      else if (bitint_big_endian)
+       pmn3 = n3;
       else if (TREE_CODE (n3) == INTEGER_CST)
        pmn3 = int_const_binop (MINUS_EXPR, p, n3);
       else
@@ -3299,16 +3540,34 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
          g = gimple_build_assign (pmn3, MINUS_EXPR, p, n3);
          insert_before (g);
        }
-      g = gimple_build_cond (LT_EXPR, n2, pmn3, NULL_TREE, NULL_TREE);
+      tree pmn2 = NULL_TREE;
+      if (bitint_big_endian)
+       {
+         if (TREE_CODE (n2) == INTEGER_CST)
+           pmn2 = int_const_binop (MINUS_EXPR, p, n2);
+         else
+           {
+             pmn2 = make_ssa_name (sizetype);
+             g = gimple_build_assign (pmn2, MINUS_EXPR, p, n2);
+             insert_before (g);
+           }
+         g = gimple_build_cond (GT_EXPR, pmn2, pmn3, NULL_TREE, NULL_TREE);
+       }
+      else
+       g = gimple_build_cond (LT_EXPR, n2, pmn3, NULL_TREE, NULL_TREE);
       edge edge_true, edge_false;
       if_then (g, profile_probability::likely (), edge_true, edge_false);
       tree idx_next;
-      tree idx = create_loop (n2, &idx_next);
+      tree idx = create_loop (bitint_big_endian ? pmn2 : n2, &idx_next);
       tree idxmn2 = make_ssa_name (sizetype);
       tree idxpn3 = make_ssa_name (sizetype);
-      g = gimple_build_assign (idxmn2, MINUS_EXPR, idx, n2);
+      g = gimple_build_assign (idxmn2,
+                              bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
+                              idx, n2);
       insert_before (g);
-      g = gimple_build_assign (idxpn3, PLUS_EXPR, idx, n3);
+      g = gimple_build_assign (idxpn3,
+                              bitint_big_endian ? MINUS_EXPR : PLUS_EXPR,
+                              idx, n3);
       insert_before (g);
       m_data_cnt = 0;
       tree t1 = handle_operand (rhs1, idx);
@@ -3333,9 +3592,12 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
       tree l = limb_access (TREE_TYPE (lhs), obj, idxmn2, true);
       g = gimple_build_assign (l, t1);
       insert_before (g);
-      g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_one_node);
+      g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                              bitint_big_endian ? size_int (-1)
+                                                : size_one_node);
       insert_before (g);
-      g = gimple_build_cond (LT_EXPR, idx_next, pmn3, NULL_TREE, NULL_TREE);
+      g = gimple_build_cond (bitint_big_endian ? GT_EXPR : LT_EXPR,
+                            idx_next, pmn3, NULL_TREE, NULL_TREE);
       insert_before (g);
       idx = make_ssa_name (sizetype);
       m_gsi = gsi_for_stmt (final_stmt);
@@ -3343,17 +3605,22 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
       edge_false = find_edge (edge_false->src, gsi_bb (m_gsi));
       edge_true = EDGE_PRED (gsi_bb (m_gsi),
                             EDGE_PRED (gsi_bb (m_gsi), 0) == edge_false);
-      add_phi_arg (phi, n2, edge_false, UNKNOWN_LOCATION);
+      add_phi_arg (phi, bitint_big_endian ? pmn2 : n2, edge_false,
+                  UNKNOWN_LOCATION);
       add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
       m_data_cnt = 0;
-      tree ms = handle_operand (rhs1, p);
+      tree ms = handle_operand (rhs1, bitint_big_endian ? size_zero_node : p);
       tree ext = ms;
       if (!types_compatible_p (TREE_TYPE (ms), m_limb_type))
        ext = add_cast (m_limb_type, ms);
       if (!(TYPE_UNSIGNED (type) && prec % limb_prec == 0)
          && !integer_zerop (n3))
        {
-         g = gimple_build_cond (LT_EXPR, idx, p, NULL_TREE, NULL_TREE);
+         if (bitint_big_endian)
+           g = gimple_build_cond (GT_EXPR, idx, size_zero_node,
+                                  NULL_TREE, NULL_TREE);
+         else
+           g = gimple_build_cond (LT_EXPR, idx, p, NULL_TREE, NULL_TREE);
          if_then (g, profile_probability::likely (), edge_true, edge_false);
          m_data_cnt = 0;
          t1 = handle_operand (rhs1, idx);
@@ -3370,13 +3637,16 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
          insert_before (g);
          t1 = gimple_assign_lhs (g);
          idxmn2 = make_ssa_name (sizetype);
-         g = gimple_build_assign (idxmn2, MINUS_EXPR, idx, n2);
+         g = gimple_build_assign (idxmn2, bitint_big_endian
+                                          ? PLUS_EXPR : MINUS_EXPR, idx, n2);
          insert_before (g);
          l = limb_access (TREE_TYPE (lhs), obj, idxmn2, true);
          g = gimple_build_assign (l, t1);
          insert_before (g);
          idx_next = make_ssa_name (sizetype);
-         g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_one_node);
+         g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                                  bitint_big_endian
+                                  ? size_int (-1) : size_one_node);
          insert_before (g);
          m_gsi = gsi_for_stmt (final_stmt);
          tree nidx = make_ssa_name (sizetype);
@@ -3388,7 +3658,9 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
          add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
          idx = nidx;
        }
-      g = gimple_build_assign (make_ssa_name (sizetype), MINUS_EXPR, idx, n2);
+      g = gimple_build_assign (make_ssa_name (sizetype),
+                              bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
+                              idx, n2);
       insert_before (g);
       idx = gimple_assign_lhs (g);
       tree sext = ext;
@@ -3414,18 +3686,35 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
       g = gimple_build_assign (l, t1);
       insert_before (g);
       g = gimple_build_assign (make_ssa_name (sizetype), PLUS_EXPR, idx,
-                              size_one_node);
+                              bitint_big_endian
+                              ? size_int (-1) : size_one_node);
       insert_before (g);
-      idx = gimple_assign_lhs (g);
-      g = gimple_build_cond (LE_EXPR, idx, p, NULL_TREE, NULL_TREE);
+      if (bitint_big_endian)
+       {
+         tree new_idx = gimple_assign_lhs (g);
+         g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
+                                NULL_TREE, NULL_TREE);
+         idx = new_idx;
+       }
+      else
+       {
+         idx = gimple_assign_lhs (g);
+         g = gimple_build_cond (LE_EXPR, idx, p, NULL_TREE, NULL_TREE);
+       }
       if_then (g, profile_probability::likely (), edge_true, edge_false);
       idx = create_loop (idx, &idx_next);
       l = limb_access (TREE_TYPE (lhs), obj, idx, true);
       g = gimple_build_assign (l, ext);
       insert_before (g);
-      g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_one_node);
+      g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                              bitint_big_endian
+                              ? size_int (-1) : size_one_node);
       insert_before (g);
-      g = gimple_build_cond (LE_EXPR, idx_next, p, NULL_TREE, NULL_TREE);
+      if (bitint_big_endian)
+       g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
+                              NULL_TREE, NULL_TREE);
+      else
+       g = gimple_build_cond (LE_EXPR, idx_next, p, NULL_TREE, NULL_TREE);
       insert_before (g);
     }
   else
@@ -3457,6 +3746,18 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
          g = gimple_build_assign (n2pn3, PLUS_EXPR, n2, n3);
          insert_before (g);
        }
+      if (bitint_big_endian)
+       {
+         if (TREE_CODE (n2pn3) == INTEGER_CST)
+           n2pn3 = int_const_binop (MINUS_EXPR, p, n2pn3);
+         else
+           {
+             g = gimple_build_assign (make_ssa_name (sizetype),
+                                      MINUS_EXPR, p, n2pn3);
+             insert_before (g);
+             n2pn3 = gimple_assign_lhs (g);
+           }
+       }
       /* For LSHIFT_EXPR, we can use handle_operand with non-INTEGER_CST
         idx even to access the most significant partial limb.  */
       m_var_msb = true;
@@ -3465,17 +3766,25 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
           counts.  Emit if (true) condition that can be optimized later.  */
        g = gimple_build_cond (NE_EXPR, boolean_true_node, boolean_false_node,
                               NULL_TREE, NULL_TREE);
+      else if (bitint_big_endian)
+       g = gimple_build_cond (NE_EXPR, n2pn3, size_int (-1), NULL_TREE,
+                              NULL_TREE);
       else
        g = gimple_build_cond (LE_EXPR, n2pn3, p, NULL_TREE, NULL_TREE);
       edge edge_true, edge_false;
       if_then (g, profile_probability::likely (), edge_true, edge_false);
       tree idx_next;
-      tree idx = create_loop (p, &idx_next);
+      tree idx = create_loop (bitint_big_endian ? size_zero_node : p,
+                             &idx_next);
       tree idxmn2 = make_ssa_name (sizetype);
       tree idxmn2mn3 = make_ssa_name (sizetype);
-      g = gimple_build_assign (idxmn2, MINUS_EXPR, idx, n2);
+      g = gimple_build_assign (idxmn2,
+                              bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
+                              idx, n2);
       insert_before (g);
-      g = gimple_build_assign (idxmn2mn3, MINUS_EXPR, idxmn2, n3);
+      g = gimple_build_assign (idxmn2mn3,
+                              bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
+                              idxmn2, n3);
       insert_before (g);
       m_data_cnt = 0;
       tree t1 = handle_operand (rhs1, idxmn2);
@@ -3500,10 +3809,13 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
       tree l = limb_access (TREE_TYPE (lhs), obj, idx, true);
       g = gimple_build_assign (l, t1);
       insert_before (g);
-      g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_int (-1));
+      g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                              bitint_big_endian
+                              ? size_one_node : size_int (-1));
       insert_before (g);
       tree sn2pn3 = add_cast (ssizetype, n2pn3);
-      g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx_next), sn2pn3,
+      g = gimple_build_cond (bitint_big_endian ? LE_EXPR : GE_EXPR,
+                            add_cast (ssizetype, idx_next), sn2pn3,
                             NULL_TREE, NULL_TREE);
       insert_before (g);
       idx = make_ssa_name (sizetype);
@@ -3512,7 +3824,8 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
       edge_false = find_edge (edge_false->src, gsi_bb (m_gsi));
       edge_true = EDGE_PRED (gsi_bb (m_gsi),
                             EDGE_PRED (gsi_bb (m_gsi), 0) == edge_false);
-      add_phi_arg (phi, p, edge_false, UNKNOWN_LOCATION);
+      add_phi_arg (phi, bitint_big_endian ? size_zero_node : p,
+                  edge_false, UNKNOWN_LOCATION);
       add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
       m_data_cnt = 0;
       if (!integer_zerop (n3))
@@ -3521,7 +3834,9 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
                                 NULL_TREE, NULL_TREE);
          if_then (g, profile_probability::likely (), edge_true, edge_false);
          idxmn2 = make_ssa_name (sizetype);
-         g = gimple_build_assign (idxmn2, MINUS_EXPR, idx, n2);
+         g = gimple_build_assign (idxmn2,
+                                  bitint_big_endian ? PLUS_EXPR : MINUS_EXPR,
+                                  idx, n2);
          insert_before (g);
          m_data_cnt = 0;
          t1 = handle_operand (rhs1, idxmn2);
@@ -3533,7 +3848,9 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
          g = gimple_build_assign (l, t1);
          insert_before (g);
          idx_next = make_ssa_name (sizetype);
-         g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_int (-1));
+         g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                                  bitint_big_endian
+                                  ? size_one_node : size_int (-1));
          insert_before (g);
          m_gsi = gsi_for_stmt (final_stmt);
          tree nidx = make_ssa_name (sizetype);
@@ -3545,17 +3862,25 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple *stmt)
          add_phi_arg (phi, idx_next, edge_true, UNKNOWN_LOCATION);
          idx = nidx;
        }
-      g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx),
-                            ssize_int (0), NULL_TREE, NULL_TREE);
+      if (bitint_big_endian)
+       g = gimple_build_cond (LE_EXPR, idx, p, NULL_TREE, NULL_TREE);
+      else
+       g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx),
+                              ssize_int (0), NULL_TREE, NULL_TREE);
       if_then (g, profile_probability::likely (), edge_true, edge_false);
       idx = create_loop (idx, &idx_next);
       l = limb_access (TREE_TYPE (lhs), obj, idx, true);
       g = gimple_build_assign (l, build_zero_cst (m_limb_type));
       insert_before (g);
-      g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_int (-1));
+      g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
+                              bitint_big_endian
+                              ? size_one_node : size_int (-1));
       insert_before (g);
-      g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx_next),
-                            ssize_int (0), NULL_TREE, NULL_TREE);
+      if (bitint_big_endian)
+       g = gimple_build_cond (LE_EXPR, idx_next, p, NULL_TREE, NULL_TREE);
+      else
+       g = gimple_build_cond (GE_EXPR, add_cast (ssizetype, idx_next),
+                              ssize_int (0), NULL_TREE, NULL_TREE);
       insert_before (g);
     }
 }
@@ -3803,7 +4128,8 @@ bitint_large_huge::arith_overflow_extract_bits (unsigned int start,
 void
 bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
                                          tree ovf, tree lhs, tree orig_obj,
-                                         gimple *stmt, tree_code code)
+                                         gimple *stmt, unsigned nelts,
+                                         tree_code code)
 {
   gimple *g;
 
@@ -3821,7 +4147,9 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
          && bitint_precision_kind (type) == bitint_prec_middle)
        lhs_type = build_nonstandard_integer_type (TYPE_PRECISION (type),
                                                   TYPE_UNSIGNED (type));
-      tree r1 = limb_access (NULL_TREE, var, size_int (0), true);
+      tree r1 = limb_access (NULL_TREE, var,
+                            bitint_big_endian
+                            ? size_int (nelts - 1) : size_zero_node, true);
       g = gimple_build_assign (make_ssa_name (m_limb_type), r1);
       insert_before (g);
       r1 = gimple_assign_lhs (g);
@@ -3829,7 +4157,9 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
        r1 = add_cast (lhs_type, r1);
       if (TYPE_PRECISION (lhs_type) > limb_prec)
        {
-         tree r2 = limb_access (NULL_TREE, var, size_int (1), true);
+         tree r2 = limb_access (NULL_TREE, var,
+                                bitint_big_endian
+                                ? size_int (nelts - 2) : size_one_node, true);
          g = gimple_build_assign (make_ssa_name (m_limb_type), r2);
          insert_before (g);
          r2 = gimple_assign_lhs (g);
@@ -3854,45 +4184,65 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type,
     }
   else
     {
-      unsigned HOST_WIDE_INT nelts = 0;
+      unsigned HOST_WIDE_INT obj_nelts = 0;
       tree atype = NULL_TREE;
       if (obj)
        {
-         nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec;
+         obj_nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec;
          if (orig_obj == NULL_TREE)
-           nelts >>= 1;
-         atype = build_array_type_nelts (m_limb_type, nelts);
+           obj_nelts >>= 1;
+         atype = build_array_type_nelts (m_limb_type, obj_nelts);
        }
       if (var && obj)
        {
          tree v1, v2;
-         tree zero;
+         tree off;
          if (orig_obj == NULL_TREE)
            {
-             zero = build_zero_cst (build_pointer_type (TREE_TYPE (obj)));
+             off = build_zero_cst (build_pointer_type (TREE_TYPE (obj)));
              v1 = build2 (MEM_REF, atype,
-                          build_fold_addr_expr (unshare_expr (obj)), zero);
+                          build_fold_addr_expr (unshare_expr (obj)), off);
            }
          else if (!useless_type_conversion_p (atype, TREE_TYPE (obj)))
            v1 = build1 (VIEW_CONVERT_EXPR, atype, unshare_expr (obj));
          else
            v1 = unshare_expr (obj);
-         zero = build_zero_cst (build_pointer_type (TREE_TYPE (var)));
-         v2 = build2 (MEM_REF, atype, build_fold_addr_expr (var), zero);
+         off = build_int_cst (build_pointer_type (TREE_TYPE (var)),
+                              bitint_big_endian
+                              ? (nelts - obj_nelts) * m_limb_size : 0);
+         v2 = build2 (MEM_REF, atype, build_fold_addr_expr (var), off);
          g = gimple_build_assign (v1, v2);
          insert_before (g);
        }
+      else if (obj && bitint_big_endian && nelts != obj_nelts)
+       {
+         gcc_assert (nelts > obj_nelts);
+         tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);
+         tree off = build_int_cst (build_pointer_type (TREE_TYPE (obj)),
+                                   (nelts - obj_nelts) * m_limb_size);
+         tree src = build2 (MEM_REF, atype,
+                            build_fold_addr_expr (unshare_expr (obj)), off);
+         g = gimple_build_call (fn, 3,
+                                build_fold_addr_expr (unshare_expr (obj)),
+                                src, build_int_cst (size_type_node,
+                                                    obj_nelts * m_limb_size));
+         insert_before (g);
+       }
       if (orig_obj == NULL_TREE && obj)
        {
          ovf = add_cast (m_limb_type, ovf);
-         tree l = limb_access (NULL_TREE, obj, size_int (nelts), true);
+         tree l = limb_access (NULL_TREE, obj,
+                               size_int (bitint_big_endian
+                                         ? obj_nelts * 2 - 1 : obj_nelts),
+                               true);
          g = gimple_build_assign (l, ovf);
          insert_before (g);
-         if (nelts > 1)
+         if (obj_nelts > 1)
            {
-             atype = build_array_type_nelts (m_limb_type, nelts - 1);
+             atype = build_array_type_nelts (m_limb_type, obj_nelts - 1);
              tree off = build_int_cst (build_pointer_type (TREE_TYPE (obj)),
-                                       (nelts + 1) * m_limb_size);
+                                       (obj_nelts + !bitint_big_endian)
+                                       * m_limb_size);
              tree v1 = build2 (MEM_REF, atype,
                                build_fold_addr_expr (unshare_expr (obj)),
                                off);
@@ -4127,18 +4477,21 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
 
   int prec4 = ovf != NULL_TREE ? prec : prec3;
   bitint_prec_kind kind = bitint_precision_kind (prec4);
-  unsigned cnt, rem = 0, fin = 0;
+  unsigned cnt, rem = 0, fin = 0, nelts;
   tree idx = NULL_TREE, idx_first = NULL_TREE, idx_next = NULL_TREE;
   bool last_ovf = (ovf == NULL_TREE
                   && CEIL (prec2, limb_prec) > CEIL (prec3, limb_prec));
   if (kind != bitint_prec_huge)
-    cnt = CEIL (prec4, limb_prec) + last_ovf;
+    nelts = cnt = CEIL (prec4, limb_prec) + last_ovf;
   else
     {
-      rem = (prec4 % (2 * limb_prec));
+      rem = prec4 % (2 * limb_prec);
       fin = (prec4 - rem) / limb_prec;
       cnt = 2 + CEIL (rem, limb_prec) + last_ovf;
-      idx = idx_first = create_loop (size_zero_node, &idx_next);
+      nelts = fin + cnt - 2;
+      idx = idx_first = create_loop (bitint_big_endian
+                                    ? size_int (nelts - 1) : size_zero_node,
+                                    &idx_next);
     }
 
   if (kind == bitint_prec_huge)
@@ -4172,19 +4525,52 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
       m_data_cnt = 0;
       tree rhs1, rhs2;
       if (kind != bitint_prec_huge)
-       idx = size_int (i);
+       idx = size_int (bitint_big_endian ? nelts - 1 - i : i);
       else if (i >= 2)
-       idx = size_int (fin + i - 2);
+       idx = size_int (bitint_big_endian ? nelts + 1 - fin - i : fin + i - 2);
       if (!last_ovf || i < cnt - 1)
        {
+         tree idx0 = idx, idx1 = idx;
+         if (bitint_big_endian
+             && CEIL ((unsigned) TYPE_PRECISION (type0), limb_prec) != nelts)
+           {
+             HOST_WIDE_INT diff
+               = ((HOST_WIDE_INT) CEIL (TYPE_PRECISION (type0), limb_prec)
+                  - (HOST_WIDE_INT) nelts);
+             if (tree_fits_uhwi_p (idx))
+               idx0 = size_int (tree_to_uhwi (idx) + diff);
+             else
+               {
+                 idx0 = make_ssa_name (sizetype);
+                 g = gimple_build_assign (idx0, PLUS_EXPR, idx,
+                                          size_int (diff));
+                 insert_before (g);
+               }
+           }
          if (type0 != TREE_TYPE (arg0))
-           rhs1 = handle_cast (type0, arg0, idx);
+           rhs1 = handle_cast (type0, arg0, idx0);
          else
-           rhs1 = handle_operand (arg0, idx);
+           rhs1 = handle_operand (arg0, idx0);
+         if (bitint_big_endian
+             && CEIL ((unsigned) TYPE_PRECISION (type1), limb_prec) != nelts)
+           {
+             HOST_WIDE_INT diff
+               = ((HOST_WIDE_INT) CEIL (TYPE_PRECISION (type1), limb_prec)
+                  - (HOST_WIDE_INT) nelts);
+             if (tree_fits_uhwi_p (idx))
+               idx1 = size_int (tree_to_uhwi (idx) + diff);
+             else
+               {
+                 idx1 = make_ssa_name (sizetype);
+                 g = gimple_build_assign (idx1, PLUS_EXPR, idx,
+                                          size_int (diff));
+                 insert_before (g);
+               }
+           }
          if (type1 != TREE_TYPE (arg1))
-           rhs2 = handle_cast (type1, arg1, idx);
+           rhs2 = handle_cast (type1, arg1, idx1);
          else
-           rhs2 = handle_operand (arg1, idx);
+           rhs2 = handle_operand (arg1, idx1);
          if (i == 0)
            data_cnt = m_data_cnt;
          if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
@@ -4240,6 +4626,8 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
          if (tree_fits_uhwi_p (idx))
            {
              unsigned limb = tree_to_uhwi (idx);
+             if (bitint_big_endian)
+               limb = nelts - 1 - limb;
              if (limb >= startlimb && limb <= endlimb)
                {
                  tree l = arith_overflow_extract_bits (start, end, rhs,
@@ -4296,14 +4684,22 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
                    cmp_code = EQ_EXPR;
                  else
                    cmp_code = GT_EXPR;
-                 g = gimple_build_cond (cmp_code, idx, size_int (startlimb),
-                                        NULL_TREE, NULL_TREE);
+                 if (bitint_big_endian)
+                   g = gimple_build_cond (swap_tree_comparison (cmp_code),
+                                          idx, size_int (nelts - 1
+                                                         - startlimb),
+                                          NULL_TREE, NULL_TREE);
+                 else
+                   g = gimple_build_cond (cmp_code, idx, size_int (startlimb),
+                                          NULL_TREE, NULL_TREE);
                  edge edge_true_true, edge_true_false, edge_false;
                  gimple *g2 = NULL;
                  if (!single_comparison)
                    g2 = gimple_build_cond (NE_EXPR, idx,
-                                           size_int (startlimb), NULL_TREE,
-                                           NULL_TREE);
+                                           size_int (bitint_big_endian
+                                                     ? nelts - 1 - startlimb
+                                                     : startlimb),
+                                           NULL_TREE, NULL_TREE);
                  if_then_if_then_else (g, g2, profile_probability::likely (),
                                        profile_probability::likely (),
                                        edge_true_true, edge_true_false,
@@ -4377,7 +4773,10 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
 
       if (var || obj)
        {
-         if (tree_fits_uhwi_p (idx) && tree_to_uhwi (idx) >= prec_limbs)
+         if (tree_fits_uhwi_p (idx)
+             && (bitint_big_endian
+                 ? nelts - 1 - tree_to_uhwi (idx)
+                 : tree_to_uhwi (idx)) >= prec_limbs)
            ;
          else if (!tree_fits_uhwi_p (idx)
                   && (unsigned) prec < (fin - (i == 0)) * limb_prec)
@@ -4386,25 +4785,48 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
                = (((unsigned) prec % limb_prec) == 0
                   || prec_limbs + 1 >= fin
                   || (prec_limbs & 1) == (i & 1));
-             g = gimple_build_cond (LE_EXPR, idx, size_int (prec_limbs - 1),
-                                    NULL_TREE, NULL_TREE);
+             if (bitint_big_endian)
+               g = gimple_build_cond (GE_EXPR, idx,
+                                      size_int (nelts - prec_limbs),
+                                      NULL_TREE, NULL_TREE);
+             else
+               g = gimple_build_cond (LE_EXPR, idx, size_int (prec_limbs - 1),
+                                      NULL_TREE, NULL_TREE);
              gimple *g2 = NULL;
              if (!single_comparison)
                g2 = gimple_build_cond (EQ_EXPR, idx,
-                                       size_int (prec_limbs - 1),
+                                       size_int (bitint_big_endian
+                                                 ? nelts - prec_limbs
+                                                 : prec_limbs - 1),
                                        NULL_TREE, NULL_TREE);
              edge edge_true_true, edge_true_false, edge_false;
              if_then_if_then_else (g, g2, profile_probability::likely (),
                                    profile_probability::unlikely (),
                                    edge_true_true, edge_true_false,
                                    edge_false);
-             tree l = limb_access (type, var ? var : obj, idx, true);
+             tree idxl = idx;
+             if (bitint_big_endian && prec_limbs != nelts)
+               {
+                 HOST_WIDE_INT diff = ((HOST_WIDE_INT) prec_limbs
+                                       - (HOST_WIDE_INT) nelts);
+                 if (tree_fits_uhwi_p (idx))
+                   idxl = size_int (tree_to_uhwi (idx) + diff);
+                 else
+                   {
+                     idxl = make_ssa_name (sizetype);
+                     g = gimple_build_assign (idxl, PLUS_EXPR, idx,
+                                              size_int (diff));
+                     insert_before (g);
+                   }
+               }
+             tree l = limb_access (type, var ? var : obj, idxl, true);
              g = gimple_build_assign (l, rhs);
              insert_before (g);
              if (!single_comparison)
                {
                  m_gsi = gsi_after_labels (edge_true_true->src);
-                 tree plm1idx = size_int (prec_limbs - 1);
+                 tree plm1idx = size_int (bitint_big_endian
+                                          ? 0 : prec_limbs - 1);
                  tree plm1type = limb_access_type (type, plm1idx);
                  l = limb_access (type, var ? var : obj, plm1idx, true);
                  if (!useless_type_conversion_p (plm1type, TREE_TYPE (rhs)))
@@ -4419,7 +4841,22 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
            }
          else
            {
-             tree l = limb_access (type, var ? var : obj, idx, true);
+             tree idxl = idx;
+             if (bitint_big_endian && prec_limbs != nelts)
+               {
+                 HOST_WIDE_INT diff = ((HOST_WIDE_INT) prec_limbs
+                                       - (HOST_WIDE_INT) nelts);
+                 if (tree_fits_uhwi_p (idx))
+                   idxl = size_int (tree_to_uhwi (idx) + diff);
+                 else
+                   {
+                     idxl = make_ssa_name (sizetype);
+                     g = gimple_build_assign (idxl, PLUS_EXPR, idx,
+                                              size_int (diff));
+                     insert_before (g);
+                   }
+               }
+             tree l = limb_access (type, var ? var : obj, idxl, true);
              if (!useless_type_conversion_p (TREE_TYPE (l), TREE_TYPE (rhs)))
                rhs = add_cast (TREE_TYPE (l), rhs);
              g = gimple_build_assign (l, rhs);
@@ -4433,16 +4870,22 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
            {
              idx = make_ssa_name (sizetype);
              g = gimple_build_assign (idx, PLUS_EXPR, idx_first,
-                                      size_one_node);
+                                      bitint_big_endian
+                                      ? size_int (-1) : size_one_node);
              insert_before (g);
            }
          else
            {
              g = gimple_build_assign (idx_next, PLUS_EXPR, idx_first,
-                                      size_int (2));
+                                      size_int (bitint_big_endian ? -2 : 2));
              insert_before (g);
-             g = gimple_build_cond (NE_EXPR, idx_next, size_int (fin),
-                                    NULL_TREE, NULL_TREE);
+             if (bitint_big_endian)
+               g = gimple_build_cond (NE_EXPR, idx_first,
+                                      size_int (nelts + 1 - fin),
+                                      NULL_TREE, NULL_TREE);
+             else
+               g = gimple_build_cond (NE_EXPR, idx_next, size_int (fin),
+                                      NULL_TREE, NULL_TREE);
              insert_before (g);
              m_gsi = gsi_for_stmt (final_stmt);
              m_bb = NULL;
@@ -4450,7 +4893,8 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt)
        }
     }
 
-  finish_arith_overflow (var, obj, type, ovf, lhs, orig_obj, stmt, code);
+  finish_arith_overflow (var, obj, type, ovf, lhs, orig_obj, stmt,
+                        prec_limbs, code);
 }
 
 /* Lower a .MUL_OVERFLOW call with at least one large/huge _BitInt
@@ -4538,6 +4982,7 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
     {
       unsigned startlimb = start / limb_prec;
       unsigned endlimb = (end - 1) / limb_prec;
+      unsigned nelts = CEIL (MAX (prec, prec2), limb_prec);
       unsigned cnt;
       bool use_loop = false;
       if (startlimb == endlimb)
@@ -4557,7 +5002,9 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
       if (cnt == 1)
        {
          tree l = limb_access (NULL_TREE, var ? var : obj,
-                               size_int (startlimb), true);
+                               size_int (bitint_big_endian
+                                         ? nelts - 1 - startlimb
+                                         :  startlimb), true);
          g = gimple_build_assign (make_ssa_name (m_limb_type), l);
          insert_before (g);
          l = arith_overflow_extract_bits (start, end, gimple_assign_lhs (g),
@@ -4591,20 +5038,25 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
            {
              tree idx, idx_next = NULL_TREE;
              if (i == 0)
-               idx = size_int (startlimb);
+               idx = size_int (bitint_big_endian
+                               ? nelts - 1 - startlimb : startlimb);
              else if (i == 2)
-               idx = size_int (endlimb);
+               idx = size_int (bitint_big_endian
+                               ? nelts - 1 - endlimb : endlimb);
              else if (use_loop)
-               idx = create_loop (size_int (startlimb + 1), &idx_next);
+               idx = create_loop (size_int (bitint_big_endian
+                                            ? nelts - startlimb - 2
+                                            : startlimb + 1), &idx_next);
              else
-               idx = size_int (startlimb + 1);
+               idx = size_int (bitint_big_endian
+                               ? nelts - startlimb - 2 : startlimb + 1);
              tree l = limb_access (NULL_TREE, var ? var : obj, idx, true);
              g = gimple_build_assign (make_ssa_name (m_limb_type), l);
              insert_before (g);
              l = gimple_assign_lhs (g);
              if (i == 0 || i == 2)
                l = arith_overflow_extract_bits (start, end, l,
-                                                tree_to_uhwi (idx),
+                                                i == 0 ? startlimb : endlimb,
                                                 check_zero);
              if (i == 0 && !check_zero)
                {
@@ -4632,11 +5084,18 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
              if (i == 1 && use_loop)
                {
                  g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
-                                          size_one_node);
+                                          bitint_big_endian
+                                          ? size_int (-1) : size_one_node);
                  insert_before (g);
-                 g = gimple_build_cond (NE_EXPR, idx_next,
-                                        size_int (endlimb + (cnt == 2)),
-                                        NULL_TREE, NULL_TREE);
+                 if (bitint_big_endian)
+                   g = gimple_build_cond (NE_EXPR, idx,
+                                          size_int (nelts - endlimb
+                                                    - (cnt == 2)),
+                                          NULL_TREE, NULL_TREE);
+                 else
+                   g = gimple_build_cond (NE_EXPR, idx_next,
+                                          size_int (endlimb + (cnt == 2)),
+                                          NULL_TREE, NULL_TREE);
                  insert_before (g);
                  edge true_edge, false_edge;
                  extract_true_false_edges_from_block (gsi_bb (m_gsi),
@@ -4661,7 +5120,8 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple *stmt)
        }
     }
 
-  finish_arith_overflow (var, obj, type, ovf, lhs, orig_obj, stmt, MULT_EXPR);
+  finish_arith_overflow (var, obj, type, ovf, lhs, orig_obj, stmt,
+                        CEIL (MAX (prec, prec2), limb_prec), MULT_EXPR);
 }
 
 /* Lower REALPART_EXPR or IMAGPART_EXPR stmt extracting part of result from
@@ -4833,19 +5293,22 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
     }
   tree fndecl = builtin_decl_explicit (fcode), res = NULL_TREE;
   unsigned cnt = 0, rem = 0, end = 0, prec = TYPE_PRECISION (type);
+  unsigned nelts = CEIL (prec, limb_prec);
   struct bq_details { edge e; tree val, addend; } *bqp = NULL;
   basic_block edge_bb = NULL;
   if (m_upwards)
     {
       tree idx = NULL_TREE, idx_first = NULL_TREE, idx_next = NULL_TREE;
       if (kind == bitint_prec_large)
-       cnt = CEIL (prec, limb_prec);
+       cnt = nelts;
       else
        {
          rem = (prec % (2 * limb_prec));
          end = (prec - rem) / limb_prec;
          cnt = 2 + CEIL (rem, limb_prec);
-         idx = idx_first = create_loop (size_zero_node, &idx_next);
+         idx = idx_first = create_loop (bitint_big_endian
+                                        ? size_int (nelts - 1)
+                                        : size_zero_node, &idx_next);
        }
 
       if (ifn == IFN_CTZ || ifn == IFN_FFS)
@@ -4867,9 +5330,10 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
        {
          m_data_cnt = 0;
          if (kind == bitint_prec_large)
-           idx = size_int (i);
+           idx = size_int (bitint_big_endian ? nelts - 1 - i : i);
          else if (i >= 2)
-           idx = size_int (end + (i > 2));
+           idx = size_int (bitint_big_endian
+                           ? nelts - 1 - end - (i > 2) : end + (i > 2));
 
          tree rhs1 = handle_operand (arg0, idx);
          if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
@@ -4909,7 +5373,9 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
              if (tree_fits_uhwi_p (idx))
                bqp[i].addend
                  = build_int_cst (integer_type_node,
-                                  tree_to_uhwi (idx) * limb_prec
+                                  (bitint_big_endian
+                                   ? nelts - 1 - tree_to_uhwi (idx)
+                                   : tree_to_uhwi (idx)) * limb_prec
                                   + (ifn == IFN_FFS));
              else
                {
@@ -4968,16 +5434,23 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
                {
                  idx = make_ssa_name (sizetype);
                  g = gimple_build_assign (idx, PLUS_EXPR, idx_first,
-                                          size_one_node);
+                                          bitint_big_endian
+                                          ? size_int (-1) : size_one_node);
                  insert_before (g);
                }
              else
                {
                  g = gimple_build_assign (idx_next, PLUS_EXPR, idx_first,
-                                          size_int (2));
+                                          size_int (bitint_big_endian
+                                                    ? -2 : 2));
                  insert_before (g);
-                 g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
-                                        NULL_TREE, NULL_TREE);
+                 if (bitint_big_endian)
+                   g = gimple_build_cond (NE_EXPR, idx_first,
+                                          size_int (cnt - 1),
+                                          NULL_TREE, NULL_TREE);
+                 else
+                   g = gimple_build_cond (NE_EXPR, idx_next, size_int (end),
+                                          NULL_TREE, NULL_TREE);
                  insert_before (g);
                  if (ifn == IFN_CTZ || ifn == IFN_FFS)
                    m_gsi = gsi_after_labels (edge_bb);
@@ -4993,7 +5466,7 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
       tree idx = NULL_TREE, idx_next = NULL_TREE, first = NULL_TREE;
       int sub_one = 0;
       if (kind == bitint_prec_large)
-       cnt = CEIL (prec, limb_prec);
+       cnt = nelts;
       else
        {
          rem = prec % limb_prec;
@@ -5026,11 +5499,12 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
        {
          m_data_cnt = 0;
          if (kind == bitint_prec_large)
-           idx = size_int (cnt - i - 1);
+           idx = size_int (bitint_big_endian ? i : cnt - i - 1);
          else if (i == cnt - 1)
-           idx = create_loop (size_int (end - 1), &idx_next);
+           idx = create_loop (size_int (bitint_big_endian ? i : end - 1),
+                              &idx_next);
          else
-           idx = size_int (end);
+           idx = bitint_big_endian ? size_zero_node : size_int (end);
 
          tree rhs1 = handle_operand (arg0, idx);
          if (!useless_type_conversion_p (m_limb_type, TREE_TYPE (rhs1)))
@@ -5115,7 +5589,9 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
            bqp[i].addend
              = build_int_cst (integer_type_node,
                               (int) prec
-                              - (((int) tree_to_uhwi (idx) + 1)
+                              - (((int) (bitint_big_endian
+                                         ? nelts - 1 - tree_to_uhwi (idx)
+                                         : tree_to_uhwi (idx)) + 1)
                                  * limb_prec) - sub_one);
          else
            {
@@ -5136,9 +5612,12 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
          if (kind == bitint_prec_huge && i == cnt - 1)
            {
              g = gimple_build_assign (idx_next, PLUS_EXPR, idx,
-                                      size_int (-1));
+                                      bitint_big_endian
+                                      ? size_one_node : size_int (-1));
              insert_before (g);
-             g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
+             g = gimple_build_cond (NE_EXPR, idx,
+                                    bitint_big_endian
+                                    ? size_int (nelts - 1) : size_zero_node,
                                     NULL_TREE, NULL_TREE);
              insert_before (g);
              edge true_edge, false_edge;
@@ -5667,14 +6146,18 @@ bitint_large_huge::lower_stmt (gimple *stmt)
                                                   TYPE_UNSIGNED (lhs_type));
       m_data_cnt = 0;
       tree rhs1 = gimple_assign_rhs1 (stmt);
-      tree r1 = handle_operand (rhs1, size_int (0));
+      unsigned int prec = TYPE_PRECISION (TREE_TYPE (rhs1));
+      unsigned int cnt = CEIL (prec, limb_prec);
+      tree r1 = handle_operand (rhs1, size_int (bitint_big_endian
+                                               ? cnt - 1 : 0));
       if (!useless_type_conversion_p (lhs_type, TREE_TYPE (r1)))
        r1 = add_cast (lhs_type, r1);
       if (TYPE_PRECISION (lhs_type) > limb_prec)
        {
          m_data_cnt = 0;
          m_first = false;
-         tree r2 = handle_operand (rhs1, size_int (1));
+         tree r2 = handle_operand (rhs1, size_int (bitint_big_endian
+                                                   ? cnt - 2 : 1));
          r2 = add_cast (lhs_type, r2);
          g = gimple_build_assign (make_ssa_name (lhs_type), LSHIFT_EXPR, r2,
                                   build_int_cst (unsigned_type_node,
@@ -5867,7 +6350,8 @@ bitint_dom_walker::before_dom_children (basic_block bb)
              tree fld = TREE_OPERAND (rhs1, 1);
              /* For little-endian, we can allow as inputs bit-fields
                 which start at a limb boundary.  */
-             if (DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1))
+             if (!bitint_big_endian
+                 && DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1))
                  && tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (fld))
                  && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld))
                      % limb_prec) == 0)
@@ -5969,9 +6453,106 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track *live,
            }
        }
     }
+  else if (bitint_big_endian
+          && is_gimple_call (stmt)
+          && gimple_call_internal_p (stmt))
+    switch (gimple_call_internal_fn (stmt))
+      {
+      case IFN_ADD_OVERFLOW:
+      case IFN_SUB_OVERFLOW:
+      case IFN_UBSAN_CHECK_ADD:
+      case IFN_UBSAN_CHECK_SUB:
+      case IFN_MUL_OVERFLOW:
+      case IFN_UBSAN_CHECK_MUL:
+       lhs = gimple_call_lhs (stmt);
+       if (lhs)
+         muldiv_p = true;
+       break;
+      default:
+       break;
+      }
 
+  auto_vec<tree, 16> worklist;
   ssa_op_iter iter;
   tree var;
+  /* On little-endian, mergeable ops process limbs from 0 up so except
+     for multiplication/division/modulo there is no risk in using the
+     same underlying variable for lhs and some operand, even when casts
+     are involved, the lhs limb is stored only after processing the source
+     limbs with the same index.
+     For multiplication/division/modulo, the libgcc library function requires
+     no aliasing between result and sources.
+     On big-endian, even mergeable ops limb processing can be problematic
+     though, because it can apply various index corrections e.g. when there
+     is a cast from operand with different number of limbs.  So, make the
+     lhs conflict with all the operands which are (for now virtually) used on
+     the current stmt if there is any mismatch in the number of limbs between
+     operands and the lhs.  */
+  if (bitint_big_endian && lhs && !muldiv_p)
+    {
+      tree ltype = TREE_TYPE (lhs);
+      if (TREE_CODE (ltype) == COMPLEX_TYPE)
+       muldiv_p = true;
+      else if (TREE_CODE (lhs) == SSA_NAME
+              && TREE_CODE (ltype) == BITINT_TYPE
+              && bitint_precision_kind (ltype) >= bitint_prec_large)
+       {
+         unsigned lnelts = CEIL (TYPE_PRECISION (ltype), limb_prec);
+         FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
+           {
+             tree type = TREE_TYPE (var);
+             if (TREE_CODE (type) == COMPLEX_TYPE)
+               type = TREE_TYPE (type);
+             if (TREE_CODE (type) == BITINT_TYPE
+                 && bitint_precision_kind (type) >= bitint_prec_large)
+               {
+                 if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
+                   {
+                     unsigned nelts = CEIL (TYPE_PRECISION (type), limb_prec);
+                     if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
+                         || lnelts != nelts)
+                       {
+                         muldiv_p = true;
+                         break;
+                       }
+                   }
+                 else
+                   worklist.safe_push (var);
+               }
+           }
+
+         while (!muldiv_p && worklist.length () > 0)
+           {
+             tree s = worklist.pop ();
+             FOR_EACH_SSA_TREE_OPERAND (var, SSA_NAME_DEF_STMT (s), iter,
+                                        SSA_OP_USE)
+               {
+                 tree type = TREE_TYPE (var);
+                 if (TREE_CODE (type) == COMPLEX_TYPE)
+                   type = TREE_TYPE (type);
+                 if (TREE_CODE (type) == BITINT_TYPE
+                     && bitint_precision_kind (type) >= bitint_prec_large)
+                   {
+                     if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
+                       {
+                         unsigned nelts = CEIL (TYPE_PRECISION (type),
+                                                limb_prec);
+                         if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
+                             || lnelts != nelts)
+                           {
+                             muldiv_p = true;
+                             break;
+                           }
+                       }
+                     else
+                       worklist.safe_push (var);
+                   }
+               }
+           }
+         worklist.truncate (0);
+       }
+    }
+
   if (!muldiv_p)
     {
       /* For stmts with more than one SSA_NAME definition pretend all the
@@ -5995,7 +6576,6 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track *live,
        def (live, var, graph);
     }
 
-  auto_vec<tree, 16> worklist;
   FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
     {
       tree type = TREE_TYPE (var);
@@ -6072,6 +6652,7 @@ gimple_lower_bitint (void)
 {
   small_max_prec = mid_min_prec = large_min_prec = huge_min_prec = 0;
   limb_prec = 0;
+  bitint_big_endian = false;
 
   unsigned int i;
   for (i = 0; i < num_ssa_names; ++i)
@@ -7056,9 +7637,25 @@ gimple_lower_bitint (void)
                          break;
                        }
                      if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE)
-                       g = gimple_build_assign (build1 (VIEW_CONVERT_EXPR,
-                                                        TREE_TYPE (c), v1),
-                                                c);
+                       {
+                         if (bitint_big_endian)
+                           {
+                             tree ptype = build_pointer_type (TREE_TYPE (v1));
+                             tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (v1));
+                             tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (c));
+                             tree off = build_int_cst (ptype,
+                                                       tree_to_uhwi (sz1)
+                                                       - tree_to_uhwi (sz2));
+                             tree vd = build2 (MEM_REF, TREE_TYPE (c),
+                                               build_fold_addr_expr (v1),
+                                               off);
+                             g = gimple_build_assign (vd, c);
+                           }
+                         else
+                           g = gimple_build_assign (build1 (VIEW_CONVERT_EXPR,
+                                                            TREE_TYPE (c),
+                                                            v1), c);
+                       }
                      else
                        {
                          unsigned HOST_WIDE_INT nelts
@@ -7067,8 +7664,21 @@ gimple_lower_bitint (void)
                          tree vtype
                            = build_array_type_nelts (large_huge.m_limb_type,
                                                      nelts);
-                         g = gimple_build_assign (build1 (VIEW_CONVERT_EXPR,
-                                                          vtype, v1),
+                         tree vd;
+                         if (bitint_big_endian)
+                           {
+                             tree ptype = build_pointer_type (TREE_TYPE (v1));
+                             tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (v1));
+                             tree sz2 = TYPE_SIZE_UNIT (vtype);
+                             tree off = build_int_cst (ptype,
+                                                       tree_to_uhwi (sz1)
+                                                       - tree_to_uhwi (sz2));
+                             vd = build2 (MEM_REF, vtype,
+                                          build_fold_addr_expr (v1), off);
+                           }
+                         else
+                           vd = build1 (VIEW_CONVERT_EXPR, vtype, v1);
+                         g = gimple_build_assign (vd,
                                                   build1 (VIEW_CONVERT_EXPR,
                                                           vtype, c));
                        }
@@ -7084,7 +7694,7 @@ gimple_lower_bitint (void)
                                                  nelts);
                      tree ptype = build_pointer_type (TREE_TYPE (v1));
                      tree off;
-                     if (c)
+                     if (c && !bitint_big_endian)
                        off = fold_convert (ptype,
                                            TYPE_SIZE_UNIT (TREE_TYPE (c)));
                      else
@@ -7096,7 +7706,7 @@ gimple_lower_bitint (void)
                  else
                    {
                      tree vd = v1;
-                     if (c)
+                     if (c && !bitint_big_endian)
                        {
                          tree ptype = build_pointer_type (TREE_TYPE (v1));
                          tree off
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-78.c b/gcc/testsuite/gcc.dg/torture/bitint-78.c
new file mode 100644 (file)
index 0000000..de092d6
--- /dev/null
@@ -0,0 +1,102 @@
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 156
+struct S156 { unsigned _BitInt(156) a : 135; _BitInt(156) b : 2; };
+struct S156 s1 = { 18071796389618321960417503813958783219759uwb, 0 };
+struct S156 s2 = { 18071796389618321960417503813958783219759uwb, -1 };
+struct T156 { _BitInt(156) a : 2; unsigned _BitInt(156) b : 135; _BitInt(156) c : 2; };
+struct T156 s3 = { -1, 10623570996611319062233232245276988766900uwb, -1 };
+struct T156 s4 = { 0, 10623570996611319062233232245276988766900uwb, 0 };
+#endif
+#if __BITINT_MAXWIDTH__ >= 230
+struct U230 { _BitInt(230) a : 140, b : 140, c : 168; unsigned _BitInt(230) d : 135; _BitInt(230) e : 2; };
+struct U230 s5 = { -1, -1, -167793869854583920719725244652254633450201662238868wb, -1, -1 };
+struct U230 s6 = { 0, 0, -167793869854583920719725244652254633450201662238868wb, 0, 0 };
+#endif
+#if __BITINT_MAXWIDTH__ >= 412
+struct S412 { unsigned _BitInt(412) a : 391; _BitInt(412) b : 2; };
+struct S412 s7 = { 3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb, 0 };
+struct S412 s8 = { 3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb, -1 };
+struct T412 { _BitInt(412) a : 2; unsigned _BitInt(412) b : 391; _BitInt(412) c : 2; };
+struct T412 s9 = { -1, 4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb, -1 };
+struct T412 s10 = { 0, 4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb, 0 };
+#endif
+#if __BITINT_MAXWIDTH__ >= 486
+struct U486 { _BitInt(486) a : 396, b : 396, c : 424; unsigned _BitInt(486) d : 391; _BitInt(486) e : 2; };
+struct U486 s11 = { -1, -1, -13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb, -1, -1 };
+struct U486 s12 = { 0, 0, 13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb, 0, 0 };
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 156
+__attribute__((noipa)) _BitInt(156)
+f1 (struct S156 *p)
+{
+  return p->a;
+}
+
+__attribute__((noipa)) _BitInt(156)
+f2 (struct T156 *q)
+{
+  return q->b;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 230
+__attribute__((noipa)) _BitInt(230)
+f3 (struct U230 *q)
+{
+  return q->c;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 412
+__attribute__((noipa)) _BitInt(412)
+f4 (struct S412 *p)
+{
+  return p->a;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 486
+__attribute__((noipa)) _BitInt(412)
+f5 (struct T412 *q)
+{
+  return q->b;
+}
+
+__attribute__((noipa)) _BitInt(486)
+f6 (struct U486 *q)
+{
+  return q->c;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 156
+  if (f1 (&s1) != 18071796389618321960417503813958783219759wb
+      || f1 (&s2) != 18071796389618321960417503813958783219759wb
+      || f2 (&s3) != 10623570996611319062233232245276988766900wb
+      || f2 (&s4) != 10623570996611319062233232245276988766900wb
+#if __BITINT_MAXWIDTH__ >= 230
+      || f3 (&s5) != -167793869854583920719725244652254633450201662238868wb
+      || f3 (&s6) != -167793869854583920719725244652254633450201662238868wb
+#if __BITINT_MAXWIDTH__ >= 412
+      || f4 (&s7) != 3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb
+      || f4 (&s8) != 3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb
+      || f5 (&s9) != 4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb
+      || f5 (&s10) != 4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb
+#if __BITINT_MAXWIDTH__ >= 486
+      || f6 (&s11) != -13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb
+      || f6 (&s12) != 13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb
+#endif
+#endif
+#endif
+      || 0)
+    __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-79.c b/gcc/testsuite/gcc.dg/torture/bitint-79.c
new file mode 100644 (file)
index 0000000..bba686c
--- /dev/null
@@ -0,0 +1,191 @@
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 255
+struct S255 { unsigned _BitInt(255) a : 255, b : 255, c : 3, d : 254, e : 255; };
+struct T255 { unsigned _BitInt(255) a : 255, b : 255, c : 4, d : 254, e : 255; };
+
+__attribute__((noipa)) void
+foo255 (struct S255 *p, unsigned _BitInt(129) x, unsigned _BitInt(129) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+bar255 (struct S255 *p, _BitInt(129) x, _BitInt(129) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+baz255 (struct T255 *p, unsigned _BitInt(129) x, unsigned _BitInt(129) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+qux255 (struct T255 *p, _BitInt(129) x, _BitInt(129) y)
+{
+  p->d = x + y;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 2047
+struct S2047 { unsigned _BitInt(2047) a : 2047, b : 2047, c : 3, d : 2046, e : 2047; };
+struct T2047 { unsigned _BitInt(2047) a : 2047, b : 2047, c : 4, d : 2046, e : 2047; };
+
+__attribute__((noipa)) void
+foo2047 (struct S2047 *p, unsigned _BitInt(1025) x, unsigned _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+bar2047 (struct S2047 *p, _BitInt(1025) x, _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+baz2047 (struct T2047 *p, unsigned _BitInt(1025) x, unsigned _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+qux2047 (struct T2047 *p, _BitInt(1025) x, _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 255
+  static struct S255 a255 = {
+    53186120754797186577260219566323862446223402596797491351049671033889795175625uwb,
+    11016010833798237411188512410350787877773522870186169967060431559664794296995uwb,
+    3uwb,
+    17651150055872917163600085508331814696406799705501438675213623161539428467390uwb,
+    46115238973717368082068120592131885017219615546561407012172308861631873123384uwb };
+  foo255 (&a255, 173345522902299812179061392904021723586uwb,
+         594746496877065132561656166247698268802uwb);
+  if (a255.a != 53186120754797186577260219566323862446223402596797491351049671033889795175625uwb
+      || a255.b != 11016010833798237411188512410350787877773522870186169967060431559664794296995uwb
+      || a255.c != 3uwb
+      || a255.d != 87527285937488017813968344288183569476uwb
+      || a255.e != 46115238973717368082068120592131885017219615546561407012172308861631873123384uwb)
+    __builtin_abort ();
+  bar255 (&a255, -295860968706196796751570199618630311203wb,
+         250268150248006479289572648514855658614wb);
+  if (a255.a != 53186120754797186577260219566323862446223402596797491351049671033889795175625uwb
+      || a255.b != 11016010833798237411188512410350787877773522870186169967060431559664794296995uwb
+      || a255.c != 3uwb
+      || a255.d != (unsigned _BitInt(254)) -45592818458190317461997551103774652589wb
+      || a255.e != 46115238973717368082068120592131885017219615546561407012172308861631873123384uwb)
+    __builtin_abort ();
+  bar255 (&a255, 295860968706196796751570199618630311203wb,
+         -250268150248006479289572648514855658614wb);
+  if (a255.a != 53186120754797186577260219566323862446223402596797491351049671033889795175625uwb
+      || a255.b != 11016010833798237411188512410350787877773522870186169967060431559664794296995uwb
+      || a255.c != 3uwb
+      || a255.d != 45592818458190317461997551103774652589uwb
+      || a255.e != 46115238973717368082068120592131885017219615546561407012172308861631873123384uwb)
+    __builtin_abort ();
+  static struct T255 b255 = {
+    22432197631110620165030705848624667816774533044127974798775792394287682890132uwb,
+    10434238915154367848470352793005517845706642883922785811579699218726683347492uwb,
+    6uwb,
+    6417359791441959589900236647374232949533098859647531540992238539547709629124uwb,
+    54440198277989626545578993065515754280754976615499904095101607562511754302923uwb };
+  baz255 (&b255, 173345522902299812179061392904021723586uwb,
+         594746496877065132561656166247698268802uwb);
+  if (b255.a != 22432197631110620165030705848624667816774533044127974798775792394287682890132uwb
+      || b255.b != 10434238915154367848470352793005517845706642883922785811579699218726683347492uwb
+      || b255.c != 6uwb
+      || b255.d != 87527285937488017813968344288183569476uwb
+      || b255.e != 54440198277989626545578993065515754280754976615499904095101607562511754302923uwb)
+    __builtin_abort ();
+  qux255 (&b255, -295860968706196796751570199618630311203wb,
+         250268150248006479289572648514855658614wb);
+  if (b255.a != 22432197631110620165030705848624667816774533044127974798775792394287682890132uwb
+      || b255.b != 10434238915154367848470352793005517845706642883922785811579699218726683347492uwb
+      || b255.c != 6uwb
+      || b255.d != (unsigned _BitInt(254)) -45592818458190317461997551103774652589wb
+      || b255.e != 54440198277989626545578993065515754280754976615499904095101607562511754302923uwb)
+    __builtin_abort ();
+  qux255 (&b255, 295860968706196796751570199618630311203wb,
+         -250268150248006479289572648514855658614wb);
+  if (b255.a != 22432197631110620165030705848624667816774533044127974798775792394287682890132uwb
+      || b255.b != 10434238915154367848470352793005517845706642883922785811579699218726683347492uwb
+      || b255.c != 6uwb
+      || b255.d != 45592818458190317461997551103774652589uwb
+      || b255.e != 54440198277989626545578993065515754280754976615499904095101607562511754302923uwb)
+    __builtin_abort ();
+#endif
+#if __BITINT_MAXWIDTH__ >= 2047
+  static struct S2047 a2047 = {
+    6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb,
+    9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb,
+    3uwb,
+    6027932121334914635743339798880634252001805340729236895908762444931865425992696360235548021447010270668149256635939999300326200737504862260957633927388112496321971644966176683706157552952742280869614447269028472263989432814406774181406202808062071176855917679050674332601759393282662520975644731312673967504693282468829790640767337337034204803704166900503628236123530078970304726919353159515533927888332084146716799866923553963246718794615364679636847688259516328750007477730553522038211483545111062280575802233656499706325920957127992496464266910119716144273601228015094027167828327389981800000899763861435249388920uwb,
+    8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb };
+  foo2047 (&a2047, 96870374520559877232425023232449835594772020210727763784623672383466424139699010793947506821373137871851733734526750376478351875022731872925672817923968593208680325422683755493846732186980639465537989170494450817375451735480623479375546788222637312722297995519801563871171551494848869504437926131454949049313uwb,
+          204286879211705664548598471253516036336450894944461293280538653272096106720692442407887688865006198655779005102679360128685207761954177030702942577918382309453894659175068179209177965184955019555984495374852658981484737374893252503438668707548935382902024863626525041196947938897658146003104268181146061978016uwb);
+  if (a2047.a != 6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb
+      || a2047.b != 9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb
+      || a2047.c != 3uwb
+      || a2047.d != 301157253732265541781023494485965871931222915155189057065162325655562530860391453201835195686379336527630738837206110505163559636976908903628615395842350902662574984597751934703024697371935659021522484545347109798860189110373875982814215495771572695624322859146326605068119490392507015507542194312601011027329uwb
+      || a2047.e != 8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb)
+    __builtin_abort ();
+  bar2047 (&a2047, -107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (a2047.a != 6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb
+      || a2047.b != 9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb
+      || a2047.c != 3uwb
+      || a2047.d != (unsigned _BitInt(2046)) -10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199wb
+      || a2047.e != 8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb)
+    __builtin_abort ();
+  bar2047 (&a2047, 107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          -96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (a2047.a != 6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb
+      || a2047.b != 9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb
+      || a2047.c != 3uwb
+      || a2047.d != 10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199uwb
+      || a2047.e != 8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb)
+    __builtin_abort ();
+  static struct T2047 b2047 = {
+    8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb,
+    10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb,
+    6uwb,
+    1798606950844195951030147598716811800015390660201512984851557206864623721164989116948214829831055619900979074616094715381713391051224334567599207518472773713480234276843296532963502302260253812173281125356773927761753111061777042155804806450961801268007533997704354588298664178382846967154936072745865025151298603472616831313827334985310238278265915811572231968955884887803234251471721609470596625338729927904093760632638752495449600773608705401930965052661588038833654673216098348474051355299310614202768960945808114868594476620223714044944623832011798187517371569683635328094981109544466514952661762483375701709483uwb,
+    15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb };
+  baz2047 (&b2047, 96870374520559877232425023232449835594772020210727763784623672383466424139699010793947506821373137871851733734526750376478351875022731872925672817923968593208680325422683755493846732186980639465537989170494450817375451735480623479375546788222637312722297995519801563871171551494848869504437926131454949049313uwb,
+          204286879211705664548598471253516036336450894944461293280538653272096106720692442407887688865006198655779005102679360128685207761954177030702942577918382309453894659175068179209177965184955019555984495374852658981484737374893252503438668707548935382902024863626525041196947938897658146003104268181146061978016uwb);
+  if (b2047.a != 8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb
+      || b2047.b != 10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb
+      || b2047.c != 6uwb
+      || b2047.d != 301157253732265541781023494485965871931222915155189057065162325655562530860391453201835195686379336527630738837206110505163559636976908903628615395842350902662574984597751934703024697371935659021522484545347109798860189110373875982814215495771572695624322859146326605068119490392507015507542194312601011027329uwb
+      || b2047.e != 15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb)
+    __builtin_abort ();
+  qux2047 (&b2047, -107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (b2047.a != 8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb
+      || b2047.b != 10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb
+      || b2047.c != 6uwb
+      || b2047.d != (unsigned _BitInt(2046)) -10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199wb
+      || b2047.e != 15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb)
+    __builtin_abort ();
+  qux2047 (&b2047, 107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          -96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (b2047.a != 8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb
+      || b2047.b != 10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb
+      || b2047.c != 6uwb
+      || b2047.d != 10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199uwb
+      || b2047.e != 15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb)
+    __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-80.c b/gcc/testsuite/gcc.dg/torture/bitint-80.c
new file mode 100644 (file)
index 0000000..283c0e0
--- /dev/null
@@ -0,0 +1,191 @@
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 255
+struct S255 { unsigned _BitInt(255) a : 255, b : 255, c : 3, d : 235, e : 255; };
+struct T255 { unsigned _BitInt(255) a : 255, b : 255, c : 4, d : 235, e : 255; };
+
+__attribute__((noipa)) void
+foo255 (struct S255 *p, unsigned _BitInt(129) x, unsigned _BitInt(129) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+bar255 (struct S255 *p, _BitInt(129) x, _BitInt(129) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+baz255 (struct T255 *p, unsigned _BitInt(129) x, unsigned _BitInt(129) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+qux255 (struct T255 *p, _BitInt(129) x, _BitInt(129) y)
+{
+  p->d = x + y;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 2047
+struct S2047 { unsigned _BitInt(2047) a : 2047, b : 2047, c : 3, d : 2027, e : 2047; };
+struct T2047 { unsigned _BitInt(2047) a : 2047, b : 2047, c : 4, d : 2027, e : 2047; };
+
+__attribute__((noipa)) void
+foo2047 (struct S2047 *p, unsigned _BitInt(1025) x, unsigned _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+bar2047 (struct S2047 *p, _BitInt(1025) x, _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+baz2047 (struct T2047 *p, unsigned _BitInt(1025) x, unsigned _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+qux2047 (struct T2047 *p, _BitInt(1025) x, _BitInt(1025) y)
+{
+  p->d = x + y;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 255
+  static struct S255 a255 = {
+    53186120754797186577260219566323862446223402596797491351049671033889795175625uwb,
+    11016010833798237411188512410350787877773522870186169967060431559664794296995uwb,
+    3uwb,
+    34443349379822557022031657812343704881254613790161917350775948942333289uwb,
+    46115238973717368082068120592131885017219615546561407012172308861631873123384uwb };
+  foo255 (&a255, 173345522902299812179061392904021723586uwb,
+         594746496877065132561656166247698268802uwb);
+  if (a255.a != 53186120754797186577260219566323862446223402596797491351049671033889795175625uwb
+      || a255.b != 11016010833798237411188512410350787877773522870186169967060431559664794296995uwb
+      || a255.c != 3uwb
+      || a255.d != 87527285937488017813968344288183569476uwb
+      || a255.e != 46115238973717368082068120592131885017219615546561407012172308861631873123384uwb)
+    __builtin_abort ();
+  bar255 (&a255, -295860968706196796751570199618630311203wb,
+         250268150248006479289572648514855658614wb);
+  if (a255.a != 53186120754797186577260219566323862446223402596797491351049671033889795175625uwb
+      || a255.b != 11016010833798237411188512410350787877773522870186169967060431559664794296995uwb
+      || a255.c != 3uwb
+      || a255.d != (unsigned _BitInt(235)) -45592818458190317461997551103774652589wb
+      || a255.e != 46115238973717368082068120592131885017219615546561407012172308861631873123384uwb)
+    __builtin_abort ();
+  bar255 (&a255, 295860968706196796751570199618630311203wb,
+         -250268150248006479289572648514855658614wb);
+  if (a255.a != 53186120754797186577260219566323862446223402596797491351049671033889795175625uwb
+      || a255.b != 11016010833798237411188512410350787877773522870186169967060431559664794296995uwb
+      || a255.c != 3uwb
+      || a255.d != 45592818458190317461997551103774652589uwb
+      || a255.e != 46115238973717368082068120592131885017219615546561407012172308861631873123384uwb)
+    __builtin_abort ();
+  static struct T255 b255 = {
+    22432197631110620165030705848624667816774533044127974798775792394287682890132uwb,
+    10434238915154367848470352793005517845706642883922785811579699218726683347492uwb,
+    6uwb,
+    43803954908428856867451333914918080831779977386765104822182973124878391uwb,
+    54440198277989626545578993065515754280754976615499904095101607562511754302923uwb };
+  baz255 (&b255, 173345522902299812179061392904021723586uwb,
+         594746496877065132561656166247698268802uwb);
+  if (b255.a != 22432197631110620165030705848624667816774533044127974798775792394287682890132uwb
+      || b255.b != 10434238915154367848470352793005517845706642883922785811579699218726683347492uwb
+      || b255.c != 6uwb
+      || b255.d != 87527285937488017813968344288183569476uwb
+      || b255.e != 54440198277989626545578993065515754280754976615499904095101607562511754302923uwb)
+    __builtin_abort ();
+  qux255 (&b255, -295860968706196796751570199618630311203wb,
+         250268150248006479289572648514855658614wb);
+  if (b255.a != 22432197631110620165030705848624667816774533044127974798775792394287682890132uwb
+      || b255.b != 10434238915154367848470352793005517845706642883922785811579699218726683347492uwb
+      || b255.c != 6uwb
+      || b255.d != (unsigned _BitInt(235)) -45592818458190317461997551103774652589wb
+      || b255.e != 54440198277989626545578993065515754280754976615499904095101607562511754302923uwb)
+    __builtin_abort ();
+  qux255 (&b255, 295860968706196796751570199618630311203wb,
+         -250268150248006479289572648514855658614wb);
+  if (b255.a != 22432197631110620165030705848624667816774533044127974798775792394287682890132uwb
+      || b255.b != 10434238915154367848470352793005517845706642883922785811579699218726683347492uwb
+      || b255.c != 6uwb
+      || b255.d != 45592818458190317461997551103774652589uwb
+      || b255.e != 54440198277989626545578993065515754280754976615499904095101607562511754302923uwb)
+    __builtin_abort ();
+#endif
+#if __BITINT_MAXWIDTH__ >= 2047
+  static struct S2047 a2047 = {
+    6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb,
+    9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb,
+    3uwb,
+    12047384745489858064414933953772839663477391272220883177150545757891750042677302445853708145531378904722301054376282458120945425051863649661639155209306286061040930046981057924193785105670446755260062214289266936409272622894864999608677838455560347293246296031941665889508903566959506861861990700494312980351508620223759760110137977058814130413350438372974774697932180418893315998700082240773617767158952812989924561352269321428579880535410771704240937834451503845844374401535603729059202374734334220483209556455967311418585395828630127849722973959209786392861438763563084218683015947661969541113478500403696370uwb,
+    8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb };
+  foo2047 (&a2047, 96870374520559877232425023232449835594772020210727763784623672383466424139699010793947506821373137871851733734526750376478351875022731872925672817923968593208680325422683755493846732186980639465537989170494450817375451735480623479375546788222637312722297995519801563871171551494848869504437926131454949049313uwb,
+          204286879211705664548598471253516036336450894944461293280538653272096106720692442407887688865006198655779005102679360128685207761954177030702942577918382309453894659175068179209177965184955019555984495374852658981484737374893252503438668707548935382902024863626525041196947938897658146003104268181146061978016uwb);
+  if (a2047.a != 6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb
+      || a2047.b != 9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb
+      || a2047.c != 3uwb
+      || a2047.d != 301157253732265541781023494485965871931222915155189057065162325655562530860391453201835195686379336527630738837206110505163559636976908903628615395842350902662574984597751934703024697371935659021522484545347109798860189110373875982814215495771572695624322859146326605068119490392507015507542194312601011027329uwb
+      || a2047.e != 8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb)
+    __builtin_abort ();
+  bar2047 (&a2047, -107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (a2047.a != 6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb
+      || a2047.b != 9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb
+      || a2047.c != 3uwb
+      || a2047.d != (unsigned _BitInt(2027)) -10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199wb
+      || a2047.e != 8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb)
+    __builtin_abort ();
+  bar2047 (&a2047, 107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          -96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (a2047.a != 6604638284533196604244471973541013618281533226364189685792053875666894057803336566484436573497392167130748586543934163550741401484647771763676964459636106203955755250170376364799937601505200975989859891863753738684249106942944581800126298385951473900411874226237184667785129620838843419470788411304260887793015638605531226504875060604515688332205834200447655374389292019856450089734989539345196623908433705347894829346923489476140677375811732806834772686417478318575505181306534740760690417577911023605293314367340174835343740361087598377394743326663660990223372181490299731215729287633035024377246940630447830332400uwb
+      || a2047.b != 9137501476482024007629903428591441562584201678803339450640010852682968378249451929368153750949595739310161107210507212794786347440833584007494934546214718055568442143768955715008628409876512331822501562467361613930394370954908550544883438576618916222169914979225020080371038560790263823334259485417483979863747127011670904476684110186667537336894469993151951433629276229957132898606324321221679211292427020775709202822704838337025228478551871438202955358400266599772607383213562964473056897194903298404105599382719634865500654814014675018495924284439422068568299533611891298495087865671200109507464285856856659661117uwb
+      || a2047.c != 3uwb
+      || a2047.d != 10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199uwb
+      || a2047.e != 8804033128404257319436391796247922558656097909723817946206424086107376571363985431643405988715302457119922790818911593984275867659318063980148880188381721682101222175837894550825446110314568257002910318459491664340963523476389547801300395551742633087402381375954250806472095890015415996293082500961651310239841690830469614433038572525199550599988220404857171911882800074918573055686438920724369407729906538787728042731530804134671860407095239208695638067647644314590947763517887856674430537735913123875082727985637440472517467667915231517115684103964725547766722895041192409825339825853271319679650626338206521967332uwb)
+    __builtin_abort ();
+  static struct T2047 b2047 = {
+    8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb,
+    10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb,
+    6uwb,
+    4790880321170629055903750609772895026632672846986739280016249738812459613115379765419988023638270768078558232945132784525166570715169427772424711358221632774714634926039540434297354515015370752168718157581893336796591613729772599089792047050683360727021739900497232167845699737421642365115219385074831571286354899965772412143441270198896667545966629183706673530731718536536465082401940906390967469028437946614351467520839911469740329315914999526738976943417735745760153747243156855057165807147066483580752278526914784843144575299178410593465362653960651398775135718996282702371931556709069927057814215337263088uwb,
+    15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb };
+  baz2047 (&b2047, 96870374520559877232425023232449835594772020210727763784623672383466424139699010793947506821373137871851733734526750376478351875022731872925672817923968593208680325422683755493846732186980639465537989170494450817375451735480623479375546788222637312722297995519801563871171551494848869504437926131454949049313uwb,
+          204286879211705664548598471253516036336450894944461293280538653272096106720692442407887688865006198655779005102679360128685207761954177030702942577918382309453894659175068179209177965184955019555984495374852658981484737374893252503438668707548935382902024863626525041196947938897658146003104268181146061978016uwb);
+  if (b2047.a != 8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb
+      || b2047.b != 10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb
+      || b2047.c != 6uwb
+      || b2047.d != 301157253732265541781023494485965871931222915155189057065162325655562530860391453201835195686379336527630738837206110505163559636976908903628615395842350902662574984597751934703024697371935659021522484545347109798860189110373875982814215495771572695624322859146326605068119490392507015507542194312601011027329uwb
+      || b2047.e != 15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb)
+    __builtin_abort ();
+  qux2047 (&b2047, -107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (b2047.a != 8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb
+      || b2047.b != 10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb
+      || b2047.c != 6uwb
+      || b2047.d != (unsigned _BitInt(2027)) -10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199wb
+      || b2047.e != 15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb)
+    __builtin_abort ();
+  qux2047 (&b2047, 107041399279853750538644610804872546664073777262361485051257422505445403341239911024662125357507942225958473152601813095133468813115195351301813567477804225231126164403591882793618380878832817133932293901187006756344358795625819716260192657246036383263988109408466592090784140040462306716053681955947029302372wb,
+          -96987190807622698460264889519367881890066987668370388919983053615401815945974432823964979317479611113155186555311657934933783458381323251774060867490977621487683905191843744141366245874982592954856173370276396645258076888821241836201856003528789429151224936212560775299953235914854472460555840121467482998173wb);
+  if (b2047.a != 8996238020280292957328835089241644192878840856627816196416318709508683098169814577226365258620493076815319486990268281142171221215928011006756119353814278158963533314155524133150379539663994828642659406032292079638106530616220996959709130065598293192861447528701351308436811527532025724876557041408124206634994855959829536357239366288943458437338903780905785942866502425145885283981390432237293769793723111403979497735186231144097215953553454988205125026498825957157417441121856068152040712774023846606695947287461796712589836037950807125680967643300197810011211640702778647554744354944603685620923084456614104269511uwb
+      || b2047.b != 10984318785160035171394274834520714981439611497142275792263219471171187866412794220589679181825290825434476603425001179842844662351028314167468349845879235198018132318905212119916242949709604719322253068999148260324480265586748667860001776565543787645340459243545680867668449541033392329858909661211654102449948990901244396803735089889644860800279108718607804327932252678544915255476214419499336896882183024344391755469834019036074623457176720435331996267496468629393048786381035430672504168120874305682383085268282415424323567923620247616970537420522283962923432940154412293415792945236923677598283314889480184388928uwb
+      || b2047.c != 6uwb
+      || b2047.d != 10054208472231052078379721285504664774006789593991096131274368890043587395265478200697146040028331112803286597290155160199685354733872099527752699986826603743442259211748138652252135003850224179076120530910610111086281906804577880058336653717246954112763173195905816790830904125607834255497841834479546304199uwb
+      || b2047.e != 15898795864009764874305090919753114555137700112966361953790245810709040722233816733280023885873997896242958848192251646902459137691931517631544750216012143606605819071183153530372060489236262856491973841038138316548406269164589694469032205076355057742341341656583075897561909452907012289408703280249378682882696627977625379823499910638320190471165330121795134411615134572598658797215197404325870770080826927165671269527854053737471231889250113654062195345706056764060545970124448748001325886598996898661788527149728584429285239380904550684885882592015572632423663763016881296460620776131666328013362700459054902525252uwb)
+    __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-81.c b/gcc/testsuite/gcc.dg/torture/bitint-81.c
new file mode 100644 (file)
index 0000000..9e7fa53
--- /dev/null
@@ -0,0 +1,174 @@
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 2048
+struct S { unsigned _BitInt(2048) a : 2048, b : 2048, c : 17, d : 1984, e : 47; };
+
+__attribute__((noipa)) void
+foo (struct S *p, unsigned _BitInt(1024) x, unsigned _BitInt(1024) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+bar (struct S *p, _BitInt(1024) x, _BitInt(1024) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+baz (struct S *p, unsigned _BitInt(1920) x, unsigned _BitInt(1920) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+qux (struct S *p, _BitInt(1920) x, _BitInt(1920) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+corge (struct S *p, unsigned _BitInt(1900) x, unsigned _BitInt(1900) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+garply (struct S *p, _BitInt(1900) x, _BitInt(1900) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+freddy (struct S *p, unsigned _BitInt(1856) x, unsigned _BitInt(1856) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+waldo (struct S *p, _BitInt(1856) x, _BitInt(1856) y)
+{
+  p->d = x + y;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 2048
+  static struct S a = {
+    -1, -1, 0,
+    463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb,
+    0 };
+  a.c = -1; a.e = -1;
+  foo (&a, 104931473307998568376284944455816272419276290777426540227909077072607565781305910683656824567560123753706639375583615231475830225655977968417978331508801616912246729932071770026909197561252489929164753507156163716727743848177523298403504040861948797263925263359073704810875557925737265337616304489108966376158uwb,
+       59920243355458337710161417863366293718453205838526168844643867766614610356796955200643446741760592218738700475637131838188996966576023003439875232851999584726009865342375796439481941924864368246882381830388251975603959739534065212652254710711469239923127731536814696621712112440700123429434845131596418309393uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1024)) (104931473307998568376284944455816272419276290777426540227909077072607565781305910683656824567560123753706639375583615231475830225655977968417978331508801616912246729932071770026909197561252489929164753507156163716727743848177523298403504040861948797263925263359073704810875557925737265337616304489108966376158uwb
+                                         + 59920243355458337710161417863366293718453205838526168844643867766614610356796955200643446741760592218738700475637131838188996966576023003439875232851999584726009865342375796439481941924864368246882381830388251975603959739534065212652254710711469239923127731536814696621712112440700123429434845131596418309393uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  bar (&a, 57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb,
+       -72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) (57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb
+                                         - 72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  bar (&a, -57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb,
+       72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) (-57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb
+                                         + 72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  baz (&a, 10046674427769604624104256297198144686571499244626667928387309298929376098027029576279399593953275611749179759608292175423884771453122373428446900092238297028886595955833507301142748242755116804512085361142982476735378897659094772516348752033708523603210976749488948779512595019051543682808058468854071972247830133684340816736701518783450117953852153823310129790997309466493287853621568286299778852505115809372004493209067461371542082762075506285274124778581566591915544298148128752861519967454244034597718098760883258950102015993032472578845214796865351706334956028690073732824uwb,
+       30612973315144170166058778463435127763223804285434461900113576569307167284342964585999954156672087142162949891238018140546663093988389394093653346239026903138243323723125156926788354976614671206441524235029939884520999076249737807760807371468017378301855151655697275608111727393644387426955142126548487675753916845926686394733479586127697929204917657250622879488360082650822591661695896650131839942739510727482535722456341390110272939230980001298487239399637003898555616301235680415285050104075063794523896618439667653475267312346144285918918555551560640876816454019806981149346uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1920)) (10046674427769604624104256297198144686571499244626667928387309298929376098027029576279399593953275611749179759608292175423884771453122373428446900092238297028886595955833507301142748242755116804512085361142982476735378897659094772516348752033708523603210976749488948779512595019051543682808058468854071972247830133684340816736701518783450117953852153823310129790997309466493287853621568286299778852505115809372004493209067461371542082762075506285274124778581566591915544298148128752861519967454244034597718098760883258950102015993032472578845214796865351706334956028690073732824uwb
+                                         + 30612973315144170166058778463435127763223804285434461900113576569307167284342964585999954156672087142162949891238018140546663093988389394093653346239026903138243323723125156926788354976614671206441524235029939884520999076249737807760807371468017378301855151655697275608111727393644387426955142126548487675753916845926686394733479586127697929204917657250622879488360082650822591661695896650131839942739510727482535722456341390110272939230980001298487239399637003898555616301235680415285050104075063794523896618439667653475267312346144285918918555551560640876816454019806981149346uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  qux (&a, 13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb,
+       -28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) (13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb
+                                         - 28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  qux (&a, -13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb,
+       28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) (-13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb
+                                         + 28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  corge (&a, 64171754625068989919140837000994640111727112880534508544592426680368730902810558177004927067680584241787685314155807083650755609249723856651964519183899537071234738837290542998681042547778311707239561819724556440611184192044964070498288365795284868545819938858772217225078359446215623326392822749370924397592547178151227397770818626413099911326742674650698762654686406157275035696691347162817031065585247142657560604671730554635740625725423122837711895800895711658181231623745755808749163225238686251279789200140461667130974133295022126714627199940806900473151584805415195uwb,
+        10507418314822331271773044775475398971761862686484059883353388622395900044257992245406697831431608445492518374055670273513238951235394317339987011165612885709605626614512380143227176716397144020233730021138060515517588833982427087228530305874044854732163307726421040484981309646463788817170356084893284995027973314236302612849097075836350102359164874937708745757469764621885202447442513857862352391464614086255770773793956362777147243363233935961477956934790795000772957425970578395645388729306937175617548119494347932433902865451670299375626936811709188316328877711066266uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1900)) (64171754625068989919140837000994640111727112880534508544592426680368730902810558177004927067680584241787685314155807083650755609249723856651964519183899537071234738837290542998681042547778311707239561819724556440611184192044964070498288365795284868545819938858772217225078359446215623326392822749370924397592547178151227397770818626413099911326742674650698762654686406157275035696691347162817031065585247142657560604671730554635740625725423122837711895800895711658181231623745755808749163225238686251279789200140461667130974133295022126714627199940806900473151584805415195uwb
+                                         + 10507418314822331271773044775475398971761862686484059883353388622395900044257992245406697831431608445492518374055670273513238951235394317339987011165612885709605626614512380143227176716397144020233730021138060515517588833982427087228530305874044854732163307726421040484981309646463788817170356084893284995027973314236302612849097075836350102359164874937708745757469764621885202447442513857862352391464614086255770773793956362777147243363233935961477956934790795000772957425970578395645388729306937175617548119494347932433902865451670299375626936811709188316328877711066266uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  garply (&a, 5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb,
+         -11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) (5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb
+                                         - 11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  garply (&a, -5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb,
+         11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) (-5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb
+                                         + 11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  freddy (&a, 469252210556625900395321429768118373804271568886989705934619437372829749132450328525095591418777876663202724364753274041797120201435942727547992144282707964490547818365755687730365454828375134854279482853064804665151021915981446605629215712706942096964289300397645214217794960755102650152979365923262599694610536124094997394321315947501858977257060703103733108840085012396782596975471783978125423726167181925777731261440167038194119207611413091278559852866397229440000783332669637577092646062124696818736270717467013532501981408774198349957822434112647379005uwb,
+         94070362846521859801705045906377514499678063439381376804210675777018147620560698746550277910632595473262065531986582027530889487288929548537551849350646108895807918918852446632833846575499156686904909401606895792588697611268444788607535104014712049735819470354574164068246431532229132503353457795214808974265484177085433521985873683760061889599206572475727862420333264989214721uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1856)) (469252210556625900395321429768118373804271568886989705934619437372829749132450328525095591418777876663202724364753274041797120201435942727547992144282707964490547818365755687730365454828375134854279482853064804665151021915981446605629215712706942096964289300397645214217794960755102650152979365923262599694610536124094997394321315947501858977257060703103733108840085012396782596975471783978125423726167181925777731261440167038194119207611413091278559852866397229440000783332669637577092646062124696818736270717467013532501981408774198349957822434112647379005uwb
+                                         + 94070362846521859801705045906377514499678063439381376804210675777018147620560698746550277910632595473262065531986582027530889487288929548537551849350646108895807918918852446632833846575499156686904909401606895792588697611268444788607535104014712049735819470354574164068246431532229132503353457795214808974265484177085433521985873683760061889599206572475727862420333264989214721uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  waldo (&a, 1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb,
+        -1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) (1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb
+                                         - 1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = -1; a.e = -1;
+  a.d = 463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  waldo (&a, -1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb,
+        1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) (-1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb
+                                         + 1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+#endif
+}