One of the first results for strict aliasing on google is this article
http://dbp-consulting.com/tutorials/StrictAliasing.html
One interesting thing I noticed is this: h
The goal for a compiler should generally be matching the intent of the code as closely as possible. In this case, the code invokes UB, but the intent should be pretty clear. My guess is that more recently compilers have been focusing on being correct than taking advantage of UB for optimization purposes.
Strict aliasing is essentially an assumption that code isn't trying to subvert the type system, which as noted by @rodrigo, gives the compiler more information it can use to optimize. If the compiler can't assume strict aliasing, it precludes a number of non-trivial optimizations, which is why C even added a restrict
qualifier (C99).
Breaking strict aliasing isn't necessary for any optimizations I can think of. In fact, in this specific case, depending on what the original intent was, you can get correct/optimized code without invoking UB...
uint32_t wswap(uint32_t ws) {
return (ws << 16) | (ws >> 16);
}
compiles to...
wswap: # @wswap
.cfi_startproc
# BB#0:
roll $16, %edi
movl %edi, %eax
retq