On Thu, Dec 01, 2016 at 08:26:47AM +0100, Jakub Jelinek wrote: > Isn't this too simplistic? I mean, if you have say dirtype of signed char > and argmin say 4096 + 32 and argmax say 4096 + 64, (signed char) arg > has range 32, 64, while I think your routine will yield -128, 127 (well, > 0 as min and -128 as max as that is what you return for signed type). > > Can't you subtract argmax - argmin (best just in wide_int, no need to build > trees), and use what you have just for the case where that number doesn't > fit into the narrower precision, otherwise if argmin - (dirtype) argmin > == argmax - (dirtype) argmax, just use (dirtype) argmin and (dirtype) argmax > as the range, and in case that it crosses a boundary figure if you can do > anything than the above? Guess all cases of signed/unsigned dirtype and/or > argtype need to be considered.
Richard noted that you could have a look at CONVERT_EXPR_CODE_P handling in extract_range_from_unary_expr. I think it is the || (vr0.type == VR_RANGE && integer_zerop (int_const_binop (RSHIFT_EXPR, int_const_binop (MINUS_EXPR, vr0.max, vr0.min), size_int (TYPE_PRECISION (outer_type))))))) part that is important here for the narrowing conversion. Jakub