http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57331
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Reduced testcase without missing return: int foo (int x) { void *p = x ? (void *) 1 : (void *) 0; __INTPTR_TYPE__ b = (__INTPTR_TYPE__) p; if (b) return 0; return 1; } The problem is that int_fits_type_p doesn't handle POINTER_TYPE_P on rhs. range_fits_type_p should already ensure that innerop is INTEGER_TYPE_P or POINTER_TYPE_P. So, either we can give up for POINTER_TYPE_P (TREE_TYPE (innerop)) always, or we could handle just the most important pointer constant (NULL), instead of the unconditional int_fits_type_p do something like && (POINTER_TYPE_P (TREE_TYPE (innerop)) ? integer_zerop (op1) : int_fits_type_p (op1, TREE_TYPE (innerop)))) (0 will fit in any pointer type), or we'd need to write larger code to do essentially what int_fits_type_p does, but using lower_bound_in_type and upper_bound_in_type instead of TYPE_{MIN,MAX}_VALUE. I'd say the last one would be overkill.