This is an archive of the discontinued LLVM Phabricator instance.

[ARM] Force LR spill in thumb2 noreturn functions
AbandonedPublic

Authored by bruno on Jul 15 2015, 2:59 PM.

Details

Summary
In ARM mode we do an opt in noreturn functions that uses branch
instead of calls and explicitly save the pc (r151645):

  mov lr, pc
  b _bar

This isn't possible in thumb2 mode because the mode bit doesnt get set
(r167657). However, we currently emit a branch and link but do not save
the LR, which leads to bad backtraces coming from noreturn functions.

Example:

define void @a() noreturn nounwind ssp {
  tail call void @b()
  unreachable
}
define void @b() noreturn nounwind ssp {
  tail call void @abort() noreturn nounwind
  unreachable
}
declare void @abort() noreturn

Currently generates:

_a:
        bl      _b
_b:
        push    {r7, lr}
        mov     r7, sp
        blx     _abort

Leading to bad backtraces. This patch generates instead:

_a:
        push    {r7, lr}
        mov     r7, sp
        bl      _b
_b:
        push    {r7, lr}
        mov     r7, sp
        blx     _abort

Diff Detail

Repository
rL LLVM

Event Timeline

bruno updated this revision to Diff 29837.Jul 15 2015, 2:59 PM
bruno retitled this revision from to [ARM] Force LR spill in thumb2 noreturn functions.
bruno updated this object.
bruno added reviewers: t.p.northover, MatzeB.
bruno set the repository for this revision to rL LLVM.
bruno added a subscriber: llvm-commits.

Hi Bruno,

I guess that it is general goodness to have the right stack trace when you debug something, but I thought noreturn + nounwind allow the compiler to trash the information for optimization purposes?

I am not saying that your patch is wrong, I am pointing out that it seems we regress some pattern to improve the debug experience, and I am not sure this is something we should do.

My 2c.

Cheers,
-Quentin

bruno abandoned this revision.Jul 16 2015, 12:47 PM

Hi Bruno,

I guess that it is general goodness to have the right stack trace when you debug something, but I thought noreturn + nounwind allow the compiler to trash the information for optimization purposes?

Yep, thanks for pointing that out, I completely missed the unwind meaning here!

I am not saying that your patch is wrong, I am pointing out that it seems we regress some pattern to improve the debug experience, and I am not sure this is something we should do.

Seems reasonable! One can always use "-funwind-tables" to override the behavior and LR will be there.
Thanks,

Isn't that the point of nounwind to not emit unwind information?

If you omit the "nounwind" from the function declaration you get your stack save.