From the C standard (see section 6.5.7 Bitwise shift operators):
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type
or if E1 has a signed type and a nonnegative value, the value of the result is the integral
part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the
resulting value is implementation-defined.
The behavior you're seeing with an infinite loop is due to the right-shift semantics of that particular implementation being: right-shifting a signed integer preserves the sign bit.
Hence, for any negative input you'll eventually end up with 0xffffffff...
(== -1), and the condition for continuing your loop will always be fulfilled.
An example:
Original input: 0x80000000
After one shift: 0xC0000000
After two shifts: 0xE0000000
After three shifts: 0xF0000000
After four shifts: 0xF8000000
etc