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

--- Comment #4 from Manjunath S Matti <mmatti.gnu at gmail dot com> ---
(In reply to Jakub Jelinek from comment #2)
> 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

I think you missed!
   return 0;

> +}
> 
> 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.

Let me have a look at this change, I will test it on cfarm121. I have a cross
compiler for s390, since the cfarm machines have been down for a week now. I
don't know whom to get in touch for these machines?

Reply via email to