https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88656

            Bug ID: 88656
           Summary: [7/8/9 Regression] lr clobbered by thumb prologue
                    before __builtin_return_address(0) reads from it
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: aoliva at gcc dot gnu.org
  Target Milestone: ---
            Target: arm-none-eabi

Alas, the fix for bug 77933 broke __builtin_return_address(0) in both leaf and
non-leaf functions on ARM -mthumb, because lr is now more likely to be used as
a scratch register to save other high registers, but then its value is used in
__builtin_return_address(0) as if it still held the return address.

This remains broken in GCC9 (I've just tried r267435).
Add "r4" to the clobber list, or compile the original testcase with
-fno-omit-frame-pointer, to get:

        push    {r[47], lr}
        mov     lr, r9
        mov     r[47], r8
        push    {r[47], lr}
[       add     r7, sp, #0      ];; -fno-omit-frame-pointer only
        mov     r0, lr


Add a call to e.g. bar() between the asm and the return, and you'll also see lr
overwritten and then used as if it still held the return address:

        push    {r4, lr}
        mov     lr, r9
        mov     r4, r8
        push    {r4, lr}
        mov     r4, lr
        bl      bar
        movs    r0, r4

Before the patch for PR 77933, lr would not be overwritten before use in any of
these cases.

Reply via email to