<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/122840>122840</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Clang incorrectly adds tailcalls after `setjmp(...)` with `-fno-builtin`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:codegen
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          alanzhao1
      </td>
    </tr>
</table>

<pre>
    Originally reported by Chromium at https://g-issues.chromium.org/issues/380508212

Example:

```c
#include <setjmp.h>

struct JpegCommon {
  jmp_buf jmpbuf;
  int cinfo;
};

int jpeg_start_decompress(int *);

int jpeg_common_start_decompress(struct JpegCommon* jpeg_common) {
  if (setjmp(jpeg_common->jmpbuf) == -1) {
 return 0;
  }
  return jpeg_start_decompress(&jpeg_common->cinfo);
}
```

If this file is compiled with `-fno-builtin`, then Clang will optimize the call to `jpeg_start_decompress(...)` as a tailcall:

```asm
jpeg_common_start_decompress:
        push    rbx
 mov     rbx, rdi
        call    _setjmp@PLT
        cmp     eax, -1
 je      .LBB0_1
        add     rbx, 200
        mov     rdi, rbx
 pop     rbx
        jmp     jpeg_start_decompress@PLT
.LBB0_1:
 xor     eax, eax
        pop     rbx
        ret
```

This is incorrect. Control flow may resume at `setjmp(...)` from another function. Because of this, the contents of the execution stack must be preserved. The tail call optimization shown above is incorrect because `jpeg_start_decompress(...)` may mess up the stack for when we later enter `jpeg_common_start_decompress(...)` at `setjmp(...)` via a `longjmp(..)` call.

This incorrect codegen only occurs with `-fno-builtin` - if we don't pass `-fno-builtin`, Clang correctly emits a call instruction (thereby preserving the stack).

godbolt: https://godbolt.org/z/1anGj6e3s
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyMVU1v8zYM_jXKhYghy_nywYc0bYYNL7Adei9kmbaVyZKhj6Tprx9kO6nXNsMMI4pFUnwekiK5c7LRiAVZP5H184IH3xpbcMX1R8tNuihNdS3-tLKRmit1BYu9sR4rKK9waK3pZOiAe2i97x3J9oQdCTs2S-lcQJeISSUxtiHsOO4Sdsx2dE13LGWE7gndv7zzrlcY7YdvsqHjK-IHy6QWKlQIJDs49KeuT1qSvYy6ztsgPPzRY3MwXWc0kO0ToXuAU9e_laGOaxlqko27UnsQUtdm3CDb5-kP3UfRqcfmzXlu_VuFwnS9RecI20UZYXvC8u_qYvD7k9U3cITt5zaE5Xe4soZoMfAjbDfTWpLsZSIR9bNnkj3DMp0ZW_TBaqA3kpFVXKf9R6QI23xxM0bmTnI45p6NkfbvNfhWOqilQpAO4nlSYQUX6VsgG7qstVmWQSovdbRiB_Atajgorhu4SKXA9F528gOjAARXCryJpo-AJkkSQW0ocAccPJcqWn0vGO46Qvf_mZXBBqanD66Nqy3f425nznD7ZAewlZzpDjgB4G3K0Yr-9et1Lu_6YUU-GC_TKDvhKEx-PT3Rt3Smzqtq7otROhPegVRyADLC600PM7TTc5r8_hy8G8obgJH-u7FzrHGZBeVHNxb992J4jZUQXy2MtSh8AgejvTUKamUu0PHYM1zoMHYJsqH3-v5MaW1NB1wb36KFOmjhpdEJPKHgwSGYsd6mMgJhtEft3biPgO8oQrQA57n4G7rgPJQIkT3aM1YJvLY4lMyYwan2-GjTmosGXpoz_osGlJP3_1WUkWWHzkHoB0wjktpYuMTCvyAo7tEC6vh7O_Jx25iV-6OgnSUHHmXK6OYmnGSRZjLPz52VMBU2qMFodQUjRLDu0bWFZexIF4Qqtqmth5479-B6jzd7cqKugJ308Z4O8ZZ67IIx3ITtYpaxvN7yI3XzGTLC8gl3Y6rSKE-y_dfRMgqmgfJB2DHl-rfTBjO3qIqsyrOcL7BIt9lml27y7XrRFqxc0XW1KreUllTUdEdxU-csW7N8l-Z8t5AFo2xN03RFU5pn60SsUhQ15UKs6pwJJCuKHZcqUeo8DLPFMMqKlLHdii4UL1G5YYgyJmIwSLafYk0Yi5PVFtF0WYYmXkklnXefh3npFRZjFO_JUtfYIty92Tng9VQ-P9TDgywuglXFlwhK34YyEaYj7BghTMuyt-aEws_n9MTvXLB_AgAA__8Ml5Aw">