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.