Message ID | ZtVqcHdRBSah6llY@tucnak |
---|---|
State | New |
Headers | show |
Series | ranger: Fix up range computation for CLZ [PR116486] | expand |
On Mon, 2 Sep 2024, Jakub Jelinek wrote: > Hi! > > The initial CLZ gimple-range-op.cc implementation handled just the > case where second argument to .CLZ is equal to prec, but in > r15-1014 I've added also handling of the -1 case. As the following > testcase shows, incorrectly though for the case where the first argument > has [0,0] range. If the second argument is prec, then the result should > be [prec,prec] and that was handled correctly, but when the second argument > is -1, the result should be [-1,-1] but instead it was incorrectly computed > as [prec-1,prec-1] (when second argument is prec, mini is 0 and maxi is > prec, while when second argument is -1, mini is -1 and maxi is prec-1). > > Fixed thusly (the actual handling is then similar to the CTZ [0,0] case), > bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. Richard. > 2024-09-02 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/116486 > * gimple-range-op.cc (cfn_clz::fold_range): If lh is [0,0] > and mini is -1, return [-1,-1] range rather than [prec-1,prec-1]. > > * gcc.dg/bitint-109.c: New test. > > --- gcc/gimple-range-op.cc.jj 2024-08-15 10:18:48.000000000 +0200 > +++ gcc/gimple-range-op.cc 2024-08-31 18:23:14.547269372 +0200 > @@ -972,8 +972,10 @@ cfn_clz::fold_range (irange &r, tree typ > { > // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec, > // return [prec, prec] or [-1, -1], otherwise ignore the range. > - if (maxi == prec || mini == -1) > - mini = maxi; > + if (maxi == prec) > + mini = prec; > + else if (mini == -1) > + maxi = -1; > } > else if (mini >= 0) > mini = newmini; > --- gcc/testsuite/gcc.dg/bitint-109.c.jj 2024-08-31 18:25:15.111715665 +0200 > +++ gcc/testsuite/gcc.dg/bitint-109.c 2024-08-31 18:26:02.015118452 +0200 > @@ -0,0 +1,25 @@ > +/* PR middle-end/116486 */ > +/* { dg-do run { target bitint } } */ > +/* { dg-options "-O2 -fno-tree-ccp" } */ > + > +unsigned u; > + > +#if __BITINT_MAXWIDTH__ >= 129 > +#define N 0x100000000000000000000000000000000uwb > +#else > +#define N 0xffffffffffffffffuwb > +#endif > + > +int > +foo (void) > +{ > + return __builtin_stdc_first_leading_one (u / N); > +} > + > +int > +main () > +{ > + int x = foo (); > + if (x) > + __builtin_abort (); > +} > > Jakub > >
--- gcc/gimple-range-op.cc.jj 2024-08-15 10:18:48.000000000 +0200 +++ gcc/gimple-range-op.cc 2024-08-31 18:23:14.547269372 +0200 @@ -972,8 +972,10 @@ cfn_clz::fold_range (irange &r, tree typ { // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec, // return [prec, prec] or [-1, -1], otherwise ignore the range. - if (maxi == prec || mini == -1) - mini = maxi; + if (maxi == prec) + mini = prec; + else if (mini == -1) + maxi = -1; } else if (mini >= 0) mini = newmini; --- gcc/testsuite/gcc.dg/bitint-109.c.jj 2024-08-31 18:25:15.111715665 +0200 +++ gcc/testsuite/gcc.dg/bitint-109.c 2024-08-31 18:26:02.015118452 +0200 @@ -0,0 +1,25 @@ +/* PR middle-end/116486 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -fno-tree-ccp" } */ + +unsigned u; + +#if __BITINT_MAXWIDTH__ >= 129 +#define N 0x100000000000000000000000000000000uwb +#else +#define N 0xffffffffffffffffuwb +#endif + +int +foo (void) +{ + return __builtin_stdc_first_leading_one (u / N); +} + +int +main () +{ + int x = foo (); + if (x) + __builtin_abort (); +}