The startup code for bare-metal AArch32 A/R shifts the CPU through all
the different modes which have their own copies of SP, updating all the
stack pointers to the same value. But it does it using C intrinsics,
leaving the register allocation to the compiler – so it's possible that
the register allocator happens to use one of the _other_ banked
registers, such as LR.
For example, when I built this code today, it happened that LR was used
to hold one of the constants written into CPSR_c to change mode. That
constant was written into the SVC mode LR before any mode changes, but
the MSR instruction that tried to use it was run in a different mode, so
it copied from _that_ mode's LR, which contained uninitialised nonsense
in place of the desired constant, triggering a boot-time crash.
I think it's safer to use a single asm statement for the whole job,
guaranteeing which registers it uses.