[clang] [llvm] [SystemZ] Add support for __builtin_setjmp and __builtin_longjmp (PR #116642)

Ulrich Weigand via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 19 14:36:53 PST 2024


================
@@ -4619,6 +4619,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
     // Buffer is a void**.
     Address Buf = EmitPointerWithAlignment(E->getArg(0));
 
+    if (getTarget().getTriple().getArch() == llvm::Triple::systemz) {
+      // Call LLVM's EH setjmp, which is lightweight.
----------------
uweigand wrote:

The underlying problem is that current implementation and documentation of the builtin is somewhat inconsistent with itself.  The documentation starts out with:

>The buffer format and the overall functioning of this intrinsic is compatible with the GCC __builtin_setjmp implementation allowing code built with the clang and GCC to interoperate.

But in GCC the format of the buffer is completely target-dependent (and actually materially different between targets), while LLVM attempts to impose some constraints on certain fields.  (These happen to be OK for the small subset of targets that currently implement these intrinsics in LLVM, but not all other GCC targets.)

Specifically, the LLVM documentation continues with

>The front end places the frame pointer in the first word

Now, even in GCC every target places the *frame pointer* in the first word, but in GCC this means the contents of the target frame pointer register, if any is used.  What clang puts into the first word, however, is the result of the `frameaddress` intrinsic - this value matches the frame pointer register contents on *some* but not all targets.  On SystemZ these values differ, which would cause incompatibilties with GCC.

Finally, the clang front-end also writes the stack pointer into the third slot.  Not only is this not even mentioned in the docs, it also does not match GCC behavior on all targets.  While indeed all targets have the to save the stack pointer somewhere, they're not all using the third slot. On SystemZ we use the fourth slot.

It is a bit unclear to me what the purpose of writing those two slots in the front end is in the first place.  It would seem more straightforward to just leave the writing of the buffer completely to the target back-end.


https://github.com/llvm/llvm-project/pull/116642


More information about the cfe-commits mailing list