https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127378

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I'd go with
2026-09-17  Jakub Jelinek  <[email protected]>
            Manjunath Matti  <[email protected]>

        PR middle-end/127378
        * gimple-lower-bitint.cc (bitint_large_huge::lower_mergeable_stmt): On
        big endian, compare idx_next in separate_ext loop against
        bo_idx + total - 1 - end, and if that wraps around, compare idx
        against 0 instead.

        * gcc.dg/bitint-145.c: New test.

--- a/gcc/gimple-lower-bitint.cc        2026-09-08 22:18:28.493021390 +0200
+++ b/gcc/gimple-lower-bitint.cc        2026-09-17 17:24:10.713167910 +0200
@@ -3271,15 +3271,18 @@ bitint_large_huge::lower_mergeable_stmt
                                       bitint_big_endian
                                       ? size_int (-1) : size_one_node);
              insert_before (g);
-             if (bitint_big_endian && rem != 0)
-               g = gimple_build_cond (NE_EXPR, idx,
-                                      size_int (bo_idx + 1),
+             /* For big-endian, if bo_idx + total - 1 - end is all ones, then
+                compare idx (which is equal to idx_next + 1) against 0
+                instead.  */
+             if (bitint_big_endian && bo_idx + total - end == 0)
+               g = gimple_build_cond (NE_EXPR, idx, size_zero_node,
                                       NULL_TREE, NULL_TREE);
              else
                g = gimple_build_cond (NE_EXPR, idx_next,
                                       size_int (bo_idx
                                                 + (bitint_big_endian
-                                                   ? 0 : end)),
+                                                   ? total - 1 - end
+                                                   : end)),
                                       NULL_TREE, NULL_TREE);
              insert_before (g);
              m_gsi = gsi_for_stmt (stmt);
--- a/gcc/testsuite/gcc.dg/bitint-145.c 2026-09-17 17:08:34.038519108 +0200
+++ b/gcc/testsuite/gcc.dg/bitint-145.c 2026-09-17 17:08:07.047875025 +0200
@@ -0,0 +1,35 @@
+/* PR middle-end/127378 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23 -O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 768
+unsigned _BitInt(512) a;
+unsigned _BitInt(768) b = -1;
+
+__attribute__((noipa)) void
+foo (unsigned _BitInt(135) *p)
+{
+  a = (_BitInt(135)) (p[0] + p[1]);
+}
+
+__attribute__((noipa)) void
+bar (unsigned _BitInt(200) *p)
+{
+  b = p[0] + p[1];
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 768
+  static unsigned _BitInt(135) p[2] = { -1, 0 };
+  static unsigned _BitInt(200) q[2] = { 1, 2 };
+  foo (p);
+  if (a != (unsigned _BitInt(512)) -1)
+    __builtin_abort ();
+  bar (q);
+  if (b != 3)
+    __builtin_abort ();
+#endif
+}

instead.
So far tested on cfarm121 with
make -j192 -k check-gcc GCC_TEST_RUN_EXPENSIVE=1
RUNTESTFLAGS="GCC_TEST_RUN_EXPENSIVE=1 --target_board=unix\{-m32,-m64\}
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"
where without this patch I see
FAIL: gcc.dg/bitint-28.c execution test
FAIL: gcc.dg/bitint-29.c execution test
FAIL: gcc.dg/bitint-30.c execution test
FAIL: gcc.dg/bitint-31.c execution test
FAIL: gcc.dg/dfp/bitint-8.c execution test
FAIL: gcc.dg/torture/bitint-16.c   -O1  execution test
FAIL: gcc.dg/torture/bitint-16.c   -O2  execution test
FAIL: gcc.dg/torture/bitint-16.c   -O2 -flto -fno-use-linker-plugin
-flto-partition=none  execution test
FAIL: gcc.dg/torture/bitint-16.c   -O2 -flto -fuse-linker-plugin
-fno-fat-lto-objects  execution test
FAIL: gcc.dg/torture/bitint-16.c   -O3 -fomit-frame-pointer -funroll-loops
-fpeel-loops -ftracer -finline-functions  execution test
FAIL: gcc.dg/torture/bitint-16.c   -O3 -g  execution test
FAIL: gcc.dg/torture/bitint-16.c   -Os  execution test
failures and with this patch the bitint-16.c failures are gone.
Going to test it on s390x next.

Reply via email to