On Tue, 21 May 2024, Jakub Jelinek wrote:
> Hi!
>
> The following testcase is miscompiled because
> strlen_pass::count_nonzero_bytes_addr doesn't handle correctly
> the !si->full_string_p case.
> If si->full_string_p, it correctly computes minlen and maxlen as
> minimum and maximum length of the '\0' terminated stgring and
> clears *nulterm (ie. makes sure !full_string_p in the ultimate
> caller) if minlen is equal or larger than nbytes and so
> '\0' isn't guaranteed to be among those bytes.
> But in the !si->full_string_p case, all we know is that there
> are [minlen,maxlen] non-zero bytes followed by unknown bytes,
> so effectively the maxlen is infinite (but caller cares about only
> the first nbytes bytes) and furthermore, we never know if there is
> any '\0' char among those, so *nulterm needs to be always cleared.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
> ok for trunk and affected release branches?
OK.
Richard.
> 2024-05-21 Jakub Jelinek
>
> PR tree-optimization/115152
> * tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes_addr): If
> !si->full_string_p, clear *nulterm and set maxlen to nbytes.
>
> * gcc.dg/pr115152.c: New test.
>
> --- gcc/tree-ssa-strlen.cc.jj 2024-04-29 11:00:45.0 +0200
> +++ gcc/tree-ssa-strlen.cc2024-05-21 13:43:31.031208000 +0200
> @@ -4829,7 +4829,7 @@ strlen_pass::count_nonzero_bytes_addr (t
>if (maxlen + 1 < nbytes)
> return false;
>
> - if (nbytes <= minlen)
> + if (nbytes <= minlen || !si->full_string_p)
> *nulterm = false;
>
>if (nbytes < minlen)
> @@ -4839,6 +4839,9 @@ strlen_pass::count_nonzero_bytes_addr (t
> maxlen = nbytes;
> }
>
> + if (!si->full_string_p)
> + maxlen = nbytes;
> +
>if (minlen < lenrange[0])
> lenrange[0] = minlen;
>if (lenrange[1] < maxlen)
> --- gcc/testsuite/gcc.dg/pr115152.c.jj2024-05-21 13:46:02.793214348
> +0200
> +++ gcc/testsuite/gcc.dg/pr115152.c 2024-05-21 12:49:38.791626073 +0200
> @@ -0,0 +1,17 @@
> +/* PR tree-optimization/115152 */
> +/* { dg-do run } */
> +/* { dg-options "-O3 -fno-tree-fre -fno-tree-dominator-opts
> -fno-tree-loop-im" } */
> +
> +int a, b, c, d;
> +signed char e[1] = { 1 };
> +
> +int
> +main ()
> +{
> + for (a = 0; a < 3; a++)
> +for (b = 0; b < 2; b++)
> + c = e[0] = e[0] ^ d;
> + if (!c)
> +__builtin_abort ();
> + return 0;
> +}
>
> Jakub
>
>
--
Richard Biener
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)