thanks Jorge.
I have try it again just like this:
int volatile addr;
addr = (int)(&__SP_INIT);
The local addr optimized.
I'm not familay with assembly, so I have not try same as your's, which defined as a pointer. It will be no effect.
The differency should be the version of arm gcc, I'm using arm-none-eabi-gcc 4.9.2, I use it for a long time, there's maybe some risk changing other version of gcc, I doubt.
Which version of gcc you are using?