For signed shifts, Op1 << Op2 in C and C++ is UB if the result cannot be
represented in the equivalent unsigned type. While a stronger statement
can be made for C, let's start small and say that a signed shift left
cannot shift out any one bits.
This doesn't seem correct for a negative LHS where we only shift out 1s -- I think that should be valid.
Essentially, we seem to have a strange circumstance here where NUW as specified is not a subset of the restrictions of NSW.
Negative LHS is forbidden in both C11 and C++14.
If E1 has a signed type and nonnegative value, and E1 × 2**E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
Otherwise, if E1 has a signed type and non-negative value, and E1 × 2**E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.
Before we go here, I think we should seriously ask whether we want to undo that restriction on shift left.
I can see arguments both for and against it.
Does GCC already do this optimization?
This revision hasn't changed for a while, removing myself from reviewers so that it does not show up in my 'waiting on others' list.
Feel free to re-add my as a reviewer later if needed.