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

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 5 06:14:12 PST 2024


================
@@ -4619,6 +4619,31 @@ 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.
+      // We're not filling any fields of the jmp_buf here and leave
+      // it all to the back-end.
+      // Current LLVM 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,
+      // while LLVM attempts to impose some constraints on certain fields.
+      // 1. LLVM documentation continues with - The front end places the frame
+      // pointer in the first word - 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.
+      // 2. 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. On SystemZ we use the fourth
+      // slot.
----------------
uweigand wrote:

> I think we should specifically call out which targets are which, for reference. No point in being overly generic.

Fair enough.

> It's worth pointing out that if the backend completely fills the buffer, it doesn't really matter if the frontend stores to the buffer before calling setjmp.

Understood.  It would still seem cleaner to not emit those stores if the back-end is going to overwrite them anyway ...

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


More information about the llvm-commits mailing list