tree-ssa-strlen: Fix up count_nonzero_bytes* [PR94015]
authorJakub Jelinek <jakub@redhat.com>
Tue, 17 Mar 2020 12:36:41 +0000 (13:36 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 17 Mar 2020 12:36:41 +0000 (13:36 +0100)
commita9a437ffc4269650e34af92c4fb095b7ed98f94a
tree477f7c4ccbcffabba6fa3732d506e543c779f371
parent5db0eb95c341d03d27b6893b22230ec8d4cb92e0
tree-ssa-strlen: Fix up count_nonzero_bytes* [PR94015]

As I said already yesterday in another PR, I'm afraid the mixing of apples
and oranges (what we are actually computing, whether what bytes are zero or
non-zero in the native representation of EXP itself or what EXP points to)
in a single function where it performs some handling which must be specific
to one or the other case unconditionally and only from time to time
determines something based on if nbytes is 0 or not will continue to bite us
again and again.
So, this patch performs at least a partial cleanup to separate those two
cases into two functions.
In addition to the separation, the patch uses e.g. ctor_for_folding so that
it does handle volatile loads properly and various other checks instead of
directly using DECL_INITIAL or does guard native_encode_expr call the way it
is guarded elsewhere (that host and target byte sizes are expected).

I've left other issues I found as is for now, like the *allnonnul being IMHO
wrongly computed (if we don't know anything about the bytes, such as if
_1 = MEM[s_2(D)];
MEM[whatever] = _1;
where nothing really is known about strlen(s) etc., the code right now
clears *nulterm and *allnul, but keeps *allnonnull set), but the callers
seem to never use that value for anything (so the question is why is it
computed and how exactly should it be defined).  Another thing I find quite
weird is the distinction between count_nonzero_bytes failing (return false)
and when it succeeds, but sets values to a don't know state (the warning is
only issued if it succeeds), plus what lenrange[2] is for.  The size of the
store should be visible already from the store statement.  Also the looking
at the type of the MEM_REF first operand to determine if it is is_char_store
is really weird, because both in user code and through sccvn where pointer
conversions are useless the type of the MEM_REF operand doesn't have to have
anything to do with what the code actually does.

2020-03-17  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/94015
* tree-ssa-strlen.c (count_nonzero_bytes): Split portions of the
function where EXP is address of the bytes being stored rather than
the bytes themselves into count_nonzero_bytes_addr.  Punt on zero
sized MEM_REF.  Use VAR_P macro and handle CONST_DECL like VAR_DECLs.
Use ctor_for_folding instead of looking at DECL_INITIAL.  Punt before
calling native_encode_expr if host or target doesn't have 8-bit
chars.  Formatting fixes.
(count_nonzero_bytes_addr): New function.

* gcc.dg/pr94015.c: New test.
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr94015.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c