More precisely, regarding E1 << E2, it is written (in the April 2023 ISO C draft):
"If E1 has a signed type and nonnegative value, and E1 × 2ᴱ² is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined."
Thus if E1 is negative, or if the result overflows, UB.