On Thu, 22 Feb 2024, Jakub Jelinek wrote:

> Hi!
> 
> Currently, bitint_large_huge::lower_mul_overflow uses cnt 1 only if
> startlimb == endlimb and in that case doesn't use a loop and handles
> everything in a special if:
>       unsigned cnt;
>       bool use_loop = false;
>       if (startlimb == endlimb)
>         cnt = 1;
>       else if (startlimb + 1 == endlimb)
>         cnt = 2;
>       else if ((end % limb_prec) == 0)
>         {
>           cnt = 2;
>           use_loop = true;
>         }
>       else
>         {
>           cnt = 3;
>           use_loop = startlimb + 2 < endlimb;
>         }
>       if (cnt == 1)
>       {
>         ...
>       }
>       else
> The loop handling for the loop exit condition wants to compare if the
> incremented index is equal to endlimb, but that is correct only if
> end is not divisible by limb_prec and there will be a straight line
> check after the loop as well for the most significant limb.  The code
> used endlimb + (cnt == 1) for that, but cnt == 1 is never true here,
> because cnt is either 2 or 3, so the right check is (cnt == 2).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2024-02-22  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/114038
>       * gimple-lower-bitint.cc (bitint_large_huge::lower_mul_overflow): Fix
>       loop exit condition if end is divisible by limb_prec.
> 
>       * gcc.dg/torture/bitint-59.c: New test.
> 
> --- gcc/gimple-lower-bitint.cc.jj     2024-02-15 09:52:40.999145971 +0100
> +++ gcc/gimple-lower-bitint.cc        2024-02-21 20:04:27.590388930 +0100
> @@ -4497,7 +4497,7 @@ bitint_large_huge::lower_mul_overflow (t
>                                          size_one_node);
>                 insert_before (g);
>                 g = gimple_build_cond (NE_EXPR, idx_next,
> -                                      size_int (endlimb + (cnt == 1)),
> +                                      size_int (endlimb + (cnt == 2)),
>                                        NULL_TREE, NULL_TREE);
>                 insert_before (g);
>                 edge true_edge, false_edge;
> --- gcc/testsuite/gcc.dg/torture/bitint-59.c.jj       2024-02-21 
> 20:07:11.028142323 +0100
> +++ gcc/testsuite/gcc.dg/torture/bitint-59.c  2024-02-21 20:07:57.854498649 
> +0100
> @@ -0,0 +1,22 @@
> +/* PR tree-optimization/114038 */
> +/* { 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__ >= 129
> +int
> +foo (unsigned _BitInt(63) x, unsigned _BitInt(129) y)
> +{
> +  return __builtin_mul_overflow_p (y, x, 0);
> +}
> +#endif
> +
> +int
> +main ()
> +{
> +#if __BITINT_MAXWIDTH__ >= 129
> +  if (!foo (90, 0x80000000000000000000000000000000uwb))
> +    __builtin_abort ();
> +#endif
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to