Message ID | Zl8X2dd4h35HO0BV@tucnak |
---|---|
State | New |
Headers | show |
Series | fold-const: Fix up CLZ handling in tree_call_nonnegative_warnv_p [PR115337] | expand |
On Tue, 4 Jun 2024, Jakub Jelinek wrote: > Hi! > > The function currently incorrectly assumes all the __builtin_clz* and .CLZ > calls have non-negative result. That is the case of the former which is UB > on zero and has [0, prec-1] return value otherwise, and is the case of the > single argument .CLZ as well (again, UB on zero), but for two argument > .CLZ is the case only if the second argument is also nonnegative (or if we > know the argument can't be zero, but let's do that just in the ranger IMHO). > > The following patch does that. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and 14? OK. Thanks, Richard. > For 13 and earlier, we can't use the testcase and the fold-const.cc change > would need to differentiate between __builtin_clz* vs. .CLZ and in the > latter case look at CLZ_DEFINED_VALUE_AT_ZERO. > > 2024-06-04 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/115337 > * fold-const.cc (tree_call_nonnegative_warnv_p) <CASE_CFN_CLZ>: > If arg1 is non-NULL, RECURSE on it, otherwise return true. > > * gcc.dg/bitint-106.c: New test. > > --- gcc/fold-const.cc.jj 2024-04-04 10:47:46.363287718 +0200 > +++ gcc/fold-const.cc 2024-06-04 10:56:57.575425348 +0200 > @@ -15241,7 +15241,6 @@ tree_call_nonnegative_warnv_p (tree type > CASE_CFN_FFS: > CASE_CFN_PARITY: > CASE_CFN_POPCOUNT: > - CASE_CFN_CLZ: > CASE_CFN_CLRSB: > case CFN_BUILT_IN_BSWAP16: > case CFN_BUILT_IN_BSWAP32: > @@ -15250,6 +15249,11 @@ tree_call_nonnegative_warnv_p (tree type > /* Always true. */ > return true; > > + CASE_CFN_CLZ: > + if (arg1) > + return RECURSE (arg1); > + return true; > + > CASE_CFN_SQRT: > CASE_CFN_SQRT_FN: > /* sqrt(-0.0) is -0.0. */ > --- gcc/testsuite/gcc.dg/bitint-106.c.jj 2024-06-04 12:00:59.017079094 +0200 > +++ gcc/testsuite/gcc.dg/bitint-106.c 2024-06-04 12:00:41.975306632 +0200 > @@ -0,0 +1,29 @@ > +/* PR tree-optimization/115337 */ > +/* { dg-do run { target bitint } } */ > +/* { dg-options "-O2" } */ > + > +#if __BITINT_MAXWIDTH__ >= 129 > +#define N 128 > +#else > +#define N 63 > +#endif > + > +_BitInt (N) g; > +int c; > + > +void > +foo (unsigned _BitInt (N + 1) z, _BitInt (N) *ret) > +{ > + c = __builtin_stdc_first_leading_one (z << N); > + _BitInt (N) y = *(_BitInt (N) *) __builtin_memset (&g, c, 5); > + *ret = y; > +} > + > +int > +main () > +{ > + _BitInt (N) x; > + foo (0, &x); > + if (c || g || x) > + __builtin_abort (); > +} > > Jakub > >
--- gcc/fold-const.cc.jj 2024-04-04 10:47:46.363287718 +0200 +++ gcc/fold-const.cc 2024-06-04 10:56:57.575425348 +0200 @@ -15241,7 +15241,6 @@ tree_call_nonnegative_warnv_p (tree type CASE_CFN_FFS: CASE_CFN_PARITY: CASE_CFN_POPCOUNT: - CASE_CFN_CLZ: CASE_CFN_CLRSB: case CFN_BUILT_IN_BSWAP16: case CFN_BUILT_IN_BSWAP32: @@ -15250,6 +15249,11 @@ tree_call_nonnegative_warnv_p (tree type /* Always true. */ return true; + CASE_CFN_CLZ: + if (arg1) + return RECURSE (arg1); + return true; + CASE_CFN_SQRT: CASE_CFN_SQRT_FN: /* sqrt(-0.0) is -0.0. */ --- gcc/testsuite/gcc.dg/bitint-106.c.jj 2024-06-04 12:00:59.017079094 +0200 +++ gcc/testsuite/gcc.dg/bitint-106.c 2024-06-04 12:00:41.975306632 +0200 @@ -0,0 +1,29 @@ +/* PR tree-optimization/115337 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2" } */ + +#if __BITINT_MAXWIDTH__ >= 129 +#define N 128 +#else +#define N 63 +#endif + +_BitInt (N) g; +int c; + +void +foo (unsigned _BitInt (N + 1) z, _BitInt (N) *ret) +{ + c = __builtin_stdc_first_leading_one (z << N); + _BitInt (N) y = *(_BitInt (N) *) __builtin_memset (&g, c, 5); + *ret = y; +} + +int +main () +{ + _BitInt (N) x; + foo (0, &x); + if (c || g || x) + __builtin_abort (); +}