On Wed, 11 Sep 2019, Jakub Jelinek wrote:

> Hi!
> 
> My recent change broke Linux kernel build, where we ICE in get_nonzero_bits
> which apparently assumes it must be called only on INTEGER_CSTs or
> SSA_NAMEs, while during generic folding it can be called say with PLUS_EXPR
> etc.
> 
> tree_nonzero_bits apparently can be called on any tree code, as it has the
> return -1 fallback, but it doesn't really handle vector types, because it
> uses TYPE_PRECISION instead of element_precision.
> get_nonzero_bits also doesn't do anything useful for vector types,
> INTEGER_CSTs aren't vectors and vector type SSA_NAMEs won't really have
> range info (though, uses element_precision).  In theory for VECTOR_CSTs we
> could or in get_nonzero_bits from all elements together or something
> similar, but still for SSA_NAMEs as we don't track anything it won't be
> useful, so this patch just punts on vector types if there is a widening
> conversion from signed.  After all, a widening conversion for vectors
> wouldn't be really a conversion, but VEC_UNPACK_{LO,HI}_EXPR.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2019-09-11  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/91725
>       * match.pd ((A / (1 << B)) -> (A >> B)): Call tree_nonzero_bits instead
>       of get_nonzero_bits, only call it for integral types.
> 
>       * gcc.c-torture/compile/pr91725.c: New test.
> 
> --- gcc/match.pd.jj   2019-09-10 10:13:29.723000308 +0200
> +++ gcc/match.pd      2019-09-10 20:14:06.164054126 +0200
> @@ -325,9 +325,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>             && (TYPE_UNSIGNED (TREE_TYPE (@1))
>                 || (element_precision (type)
>                     == element_precision (TREE_TYPE (@1)))
> -               || (get_nonzero_bits (@0)
> -                   & wi::mask (element_precision (TREE_TYPE (@1)) - 1, true,
> -                               element_precision (type))) == 0))))
> +               || (INTEGRAL_TYPE_P (type)
> +                   && (tree_nonzero_bits (@0)
> +                       & wi::mask (element_precision (TREE_TYPE (@1)) - 1,
> +                                   true,
> +                                   element_precision (type))) == 0)))))
>    (rshift @0 @2)))
>  
>  /* Preserve explicit divisions by 0: the C++ front-end wants to detect
> --- gcc/testsuite/gcc.c-torture/compile/pr91725.c.jj  2019-09-10 
> 20:09:39.499987576 +0200
> +++ gcc/testsuite/gcc.c-torture/compile/pr91725.c     2019-09-10 
> 20:08:21.302141038 +0200
> @@ -0,0 +1,7 @@
> +/* PR middle-end/91725 */
> +
> +unsigned long long
> +foo (unsigned long long x, unsigned long long y, int z)
> +{
> +  return (x + y) / (1 << z);
> +}
> 
>       Jakub
> 

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

Reply via email to