https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82158
--- Comment #5 from Peter Cordes <peter at cordes dot ca> --- (In reply to Ramana Radhakrishnan from comment #4) > It's a "feature" - if the function really doesn't return, then there is no > real requirement to save and restore all callee-saved registers. > > A deliberate choice when computing the save register mask - all that we are > providing is an ability to backtrace out of such cases That's what I thought; just be able to print backtraces. Good point about -fno-exceptions. I forgot I was building as C in the first place. :P > I can see that other backends have similar techniques - x86_64 appears to > trash %esi in the experiments I did and it does look like %esi is a callee > saved register. No, %esi is call-clobbered in x86-64 (Windows and System V). It's call-preserved in x86-32. (-m32) I checked again with -fno-exceptions, and none of the other backends on godbolt do this. I constructed a better test-case (https://godbolt.org/g/pAgsnA) that makes it easier to compare code-gen for a function that returns (without using _Noreturn) vs. a _Noreturn function that calls done(). So even if you aren't sure of the calling convention on a target, you can look for fewer store instructions, or lack of them before a reg-reg move. In all cases except ARM32, gcc stores two regs before moving arg regs into them. So there's also a missed-optimization for everything except ARM32, for functions that really don't return. I suppose that's a separate bug that I should open.