https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87871
--- Comment #9 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- (In reply to Wilco from comment #8) > (In reply to Segher Boessenkool from comment #5) > > The first one just needs an xfail. I don't know if it should be *-*-* there > > or only arm*-*-* should be added. > > > > The other two need some debugging by someone who knows the target and/or > > these tests. > > The previous code for Arm was: > > cbz r0, .L5 > push {r4, lr} > mov r4, r0 > bl foo > movw r2, #:lower16:.LANCHOR0 > movt r2, #:upper16:.LANCHOR0 > add r4, r4, r0 > str r4, [r2] > pop {r4, pc} > .L5: > movs r0, #1 > bx lr > > Now it fails to shrinkwrap: > > push {r4, lr} > mov r4, r0 > cmp r4, #0 > moveq r0, #1 > beq .L3 > bl foo > ldr r2, .L7 > add r3, r4, r0 > str r3, [r2] > .L3: > pop {r4, lr} > bx lr > > It seems shrinkwrapping is more random, sometimes it's done as expected, > sometimes it is not. It was more consistent on older GCC's. This looks like another fallout of not allowing combine to merge with hard regs. Previously the CBZ could be moved outside of the prologue because it operated directly on the incoming hard reg. Now it only sees the value after the copy into the pseudo, which is a call-saved reg because it's live over the call.