[PATCH] D84044: [AArch64][SVE] Add missing unwind info for SVE registers.

Richard Sandiford via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 27 13:24:24 PDT 2020


rsandifo-arm added a comment.

In D84044#2176118 <https://reviews.llvm.org/D84044#2176118>, @sdesmalen wrote:

> Yes, great spot! The caller should assume that all SVE registers are clobbered by the unwinder if the function _may_ throw an exception. I think I'll create a separate patch to fix this, as it's not necessarily something to do with how LLVM emits the unwind info, but rather a bug where the caller doesn't honour the right CC.


I suspect we're in violent agreement here, but just in case: the SVE PCS rules apply as normal in Eli's testcase: normal returns from g1 and g2 preserve Z8-Z23 and P4 <https://reviews.llvm.org/P4>-P15 regardless of what exceptions (if any) get thrown during the calls to g1 and g2.  But the only state preserved across exception edges is the state that is preserved by the base ABI.  This applies:

- to Advanced SIMD vector PCS functions as well as SVE functions (in particular V16-V23 are not preserved across an exception edge)
- to asynchronous exceptions as well as synchronous exceptions

In other words, this isn't a property of the calling convention so much as a property of the unwinder itself.  The same situation would apply for something like:

  void g(svfloat32_t);
  svfloat32_t f(svfloat32_t x, int *y) {
    try { *y = 0; } catch (...) { g(x); throw; }
    return x;
  }

if non-call exceptions are enabled: the exception edge from the possibly-faulting store to `*y` would clobber everything except the state preserved by a normal call.

Of course, nothing ever clobbers the SVE register state for normal returns from `f`, and in particular, this exception handler never returns from `f`.  So the ideal function body would be something like:

  f:
          addvl   sp, sp, #-1
          str     z0, [sp]       // Save x in case the EH handler gets run
          str     wzr, [x0]
          addvl   sp, sp, #1
          ret                    // z0 still contains x here

FWIW, GCC handles this by modelling the clobbers on the EH edge itself, rather than as being a property of any call (since, as in the example above, there might not be a call).  I haven't checked if LLVM does the same.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84044/new/

https://reviews.llvm.org/D84044





More information about the llvm-commits mailing list