fold: Fix up strn{case,}cmp folding [PR98771]
authorJakub Jelinek <jakub@redhat.com>
Mon, 25 Jan 2021 09:03:40 +0000 (10:03 +0100)
committerJakub Jelinek <jakub@redhat.com>
Mon, 25 Jan 2021 09:03:40 +0000 (10:03 +0100)
commitb7a0507ad9f07492a37325a2f494ed933b217a9a
treefd54e67d9e788f353a70544dd36fef753603546e
parent389b67feac78c8f21c6946bf8e36a16060f45728
fold: Fix up strn{case,}cmp folding [PR98771]

As mentioned in the PR, the compiler behaves differently during strncmp
and strncasecmp folding between 32-bit and 64-bit hosts targeting 64-bit
target.  I think that is highly undesirable.

The culprit is the host_size_t_cst_p predicate that is used by
fold_const_call, which punts if the target size_t constants don't fit into
host size_t.  This patch gets rid of that behavior, instead it punts the
same when it doesn't fit into uhwi.

The predicate was used for strncmp and strncasecmp folding and for bcmp, memcmp and
memchr folding.
The constant is in all cases compared to 0, we can do that whether it fits
into size_t or unsigned HOST_WIDE_INT, then it is used in s2 <= s0 or
s2 <= s1 comparisons where s0 and s1 already have uhwi type and represent
the sizes of the objects.
The important difference is for strn{,case}cmp folding, we pass that s2
value as the last argument to the host functions comparing the c_getstr
results.  If s2 fits into size_t, then my patch makes no difference,
but if it is larger, we know the 2 c_getstr objects need to fit into the
host address space, so larger s2 should just act essentially as strcmp
or strcasecmp; as none of those objects can occupy 100% of the address
space, using MIN (SIZE_MAX, s2) achieves that.

2021-01-25  Jakub Jelinek  <jakub@redhat.com>

PR testsuite/98771
* fold-const-call.c (host_size_t_cst_p): Renamed to ...
(size_t_cst_p): ... this.  Check and store unsigned HOST_WIDE_INT
value rather than host size_t.
(fold_const_call): Change type of s2 from size_t to
unsigned HOST_WIDE_INT.  Use size_t_cst_p instead of
host_size_t_cst_p.  For strncmp calls, pass MIN (s2, SIZE_MAX)
instead of s2 as last argument.
gcc/fold-const-call.c