Any range information the compiler intuits from signed values not overflowing could, in principle, be given explicitly with the following code:
if (foo > 1000) __builtin_unreachable();
Or macros that make that kind of thing look prettier. I prefer using unsigned values everywhere for both safety and semantics. (It's not possible to have a negative number of bananas, so why should I use a type that admits a value of -3 bananas?)
Clang also has a more explicit __builtin_assume(expression) builtin, although anecdotally GCC makes better use of these hints. Folly has a function to make it portable:
I always use signed ints precisely because -3 bananas is more obviously incorrect than 2147483645 bananas. The opportunity of storing special 'null' values is also useful.