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? 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