Correct. Bit shifting is fast, so multiplication and division by constants that are powers of two are often optimized to bit shifts.
The optimization differs though depending on whether you are dealing with signed or unsigned integers. For unsigned the case is simple. A shift right (logical = zero fill the vacated bits) divides by 2, rounding odd numbers down. For signed numbers a simple shift right (arithmetic = sign extend the vacated bits) will also divide by 2, and round odd numbers down. However, signed numbers are generally rounded towards 0. This means positive numbers are rounded down, and negative numbers are rounded up. To do this, a correction must be performed in case the number was negative. Without the correction you'd get results like -1 / 2 = -1, or -1 / 4 = -1. With the correction, which the compiler will automatically insert for signed values, -1 / 2 = 0. To do this, the sign bit is added back into the low order bits of the value that are being shifted out before the shift is performed. The number of bits affected depends on the power of 2 you are dividing by. In general, you need to add (divisor - 1) to the value before shifting, if the number was negative. Because of this correction, you need an extra 2-3 instructions ahead of the shift, or more depending on compiler and optimization settings. All of this will still be much faster than an actual divide instruction, however the optimization is less for signed values than for unsigned values.
There are a number of other optimizations that also work better for unsigned values. A bit unfortunate, since many programmers are lazy and just type "int" when what they're really dealing with should be "unsigned int". I prefer environments that shorten this to things like "uint" or "sint" for signed or unsigned numbers. It makes it much more likely the programmer will declare what they actually need, rather than what's artificially convenient.
Of interesting note, since multiplication is so well behaved, even numbers that are not powers of two were often implemented with bit shifts and adds, since this used to be faster than a simple multiply instruction. To multiply a * 9 = a * (8 + 1) = a * 8 + a, you can shift left by 3 (multiply by 8 ), and add in the source (the 1) to obtain the result of multiplying by 9. This was aided by instructions such as LEA (Load Effective Address). LEA can be used to calculate memory addresses, using the memory addressing mechanism available to most instructions. Despite it's appearance the LEA instruction is an arithmetic instruction, not a memory access instruction. The LEA instruction makes use of the SIB (Scale/Index/Base) byte used by memory instructions to perform (scale * index + base). The SIB byte encodes two registers (the base and the index) in 3-bits each (there are 8 general purpose registers), and uses the remaining 2 bits to specify a scale of either 1, 2, 4, or 8. This was to aid in array address calculations, since elements sizes were typically 1, 2, 4, or 8 bytes. However, by setting the base and the index to the same register, this allows the CPU to multiply by 2, 3, 5, or 9, using only 1 fast simple instruction. The encoding of the shift instruction is smaller than LEA, so SHL makes a better choice than LEA when multiplying by 2.