On Fri, 22 Jan 2021, Jakub Jelinek wrote:

> Hi!
> 
> 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2021-01-22  Jakub Jelinek  <ja...@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.jj  2021-01-04 10:25:37.902244366 +0100
> +++ gcc/fold-const-call.c     2021-01-22 11:23:31.571000548 +0100
> @@ -53,16 +53,15 @@ complex_cst_p (tree t)
>    return TREE_CODE (t) == COMPLEX_CST;
>  }
>  
> -/* Return true if ARG is a constant in the range of the host size_t.
> +/* Return true if ARG is a size_type_node constant.
>     Store it in *SIZE_OUT if so.  */
>  
>  static inline bool
> -host_size_t_cst_p (tree t, size_t *size_out)
> +size_t_cst_p (tree t, unsigned HOST_WIDE_INT *size_out)
>  {
>    if (types_compatible_p (size_type_node, TREE_TYPE (t))
>        && integer_cst_p (t)
> -      && (wi::min_precision (wi::to_wide (t), UNSIGNED)
> -       <= sizeof (size_t) * CHAR_BIT))
> +      && tree_fits_uhwi_p (t))
>      {
>        *size_out = tree_to_uhwi (t);
>        return true;
> @@ -1767,23 +1766,22 @@ fold_const_call (combined_fn fn, tree ty
>  {
>    const char *p0, *p1;
>    char c;
> -  unsigned HOST_WIDE_INT s0, s1;
> -  size_t s2 = 0;
> +  unsigned HOST_WIDE_INT s0, s1, s2 = 0;
>    switch (fn)
>      {
>      case CFN_BUILT_IN_STRNCMP:
> -      if (!host_size_t_cst_p (arg2, &s2))
> +      if (!size_t_cst_p (arg2, &s2))
>       return NULL_TREE;
>        if (s2 == 0
>         && !TREE_SIDE_EFFECTS (arg0)
>         && !TREE_SIDE_EFFECTS (arg1))
>       return build_int_cst (type, 0);
>        else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
> -     return build_int_cst (type, strncmp (p0, p1, s2));
> +     return build_int_cst (type, strncmp (p0, p1, MIN (s2, SIZE_MAX)));
>        return NULL_TREE;
>  
>      case CFN_BUILT_IN_STRNCASECMP:
> -      if (!host_size_t_cst_p (arg2, &s2))
> +      if (!size_t_cst_p (arg2, &s2))
>       return NULL_TREE;
>        if (s2 == 0
>         && !TREE_SIDE_EFFECTS (arg0)
> @@ -1791,13 +1789,13 @@ fold_const_call (combined_fn fn, tree ty
>       return build_int_cst (type, 0);
>        else if ((p0 = c_getstr (arg0))
>              && (p1 = c_getstr (arg1))
> -            && strncmp (p0, p1, s2) == 0)
> +            && strncmp (p0, p1, MIN (s2, SIZE_MAX)) == 0)
>       return build_int_cst (type, 0);
>        return NULL_TREE;
>  
>      case CFN_BUILT_IN_BCMP:
>      case CFN_BUILT_IN_MEMCMP:
> -      if (!host_size_t_cst_p (arg2, &s2))
> +      if (!size_t_cst_p (arg2, &s2))
>       return NULL_TREE;
>        if (s2 == 0
>         && !TREE_SIDE_EFFECTS (arg0)
> @@ -1811,7 +1809,7 @@ fold_const_call (combined_fn fn, tree ty
>        return NULL_TREE;
>  
>      case CFN_BUILT_IN_MEMCHR:
> -      if (!host_size_t_cst_p (arg2, &s2))
> +      if (!size_t_cst_p (arg2, &s2))
>       return NULL_TREE;
>        if (s2 == 0
>         && !TREE_SIDE_EFFECTS (arg0)
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to