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)