https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92308
--- Comment #4 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- So taking the example I posted in the initial report and compiling with trunk for arm -mcpu=cortex-m4 -mthumb -Os, we get: ldr r3, .L2 movs r2, #1 str r2, [r3, #2060] movs r2, #2 str r2, [r3, #2064] movs r2, #3 str r2, [r3, #2052] movs r2, #4 str r2, [r3, #2076] movs r2, #6 str r2, [r3, #2048] bx lr .L2: .word 0x43fe1000 Because the backend (in TARGET_LEGITIMIZE_ADDRESS) has had to guess at a base, and has chosen to split off the bottom 12 bits into the offset (giving the maximum range and therefore the most likely base to form as many CSEs as possible). But using this base means that the str instructions need a 32-bit encoding as the offsets exceed the limit for the 16-bit encoded version. We could choose to to split off only 7 bits of offset, then we could use the smaller encoding, but now we reduce the likelihood of finding common bases. But there's no real need to do this by splitting the bits with a mask, if we have a global view of what's going on (the problem is that TARGET_LEGITIMIZE_ADDRESS does not have a global view); we could pick the original BB_ADDRESS as the base just as easily as any other. Also note that if BB_ADDRESS were changed to 0x43fefff8, then there is practically no chance of the back-end finding an optimal base as the address range spans a mask boundary, regardless of which mask we chose.