What we're looking for here is a certain sort of sane non-extremist portability. We want to support hardware that actually ships today as the primary application processor for a cell phone, laptop/notebook, tablet, desktop, or serious SQL or web server.
We don't want to think about opcodes or registers.
The hardware in use today is ARM, x86, and POWER. All of these normally support unaligned accesses, and so we expect that of the language. We see it in x86 except with that weird instruction that gcc wrongly used (it is slower) in this article. We see it in ARMv7 and ARMv8. We see it in POWER, going back at least to the PowerPC days.
All 3 of those architectures support little-endian code. It is now extremely rare to find big-endian ARM, and POWER is rapidly heading that way. It is essentially required by the web now, due to javascript Typed Arrays exposing endianness.
RISC-V is the same way: little-endian with support for unaligned access. This is the future.
The type of control and predictability desired is as follows:
If I have a 32-bit value, and I shift it left by 40 bits, there are only two reasonable answers. The compiler can do exactly as requested, producing a zero. The compiler can mask the shift down to 5 bits first, because hardware commonly does this, causing the shift to be by 8 bits. It is not at all OK for the compiler to do weird shit however, such as assuming that the code path can never be hit and then doing dead code elimination.
If I have a 32-bit 0x7fffffff and I shift it left by 1, that should produce the obvious result even if the data type is signed. (it is -2 in that case) Again, it is unacceptable to do weird shit. It is simply not OK to presume that my code will not run (due to an allowance made in the C standard for some 1960s hardware) and then do dead code elimination.
If I have a signed value and I shift it right, I expect the compiler to use the opcode for a signed shift. At least gcc promises to do this.