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

    <tr>
        <th>Summary</th>
        <td>
            crash on load of under-aligned i128 from coroutine frame
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            coroutines
      </td>
    </tr>

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

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

<pre>
    Using clang/llvm/libc++ at head (09966960c692be63b192448e8c2b6bfebad3c3b8):

```
#include <coroutine>

// Boilerplate based on https://theshoemaker.de/posts/yet-another-cpp-coroutine-tutorial
class Task {
public:
    struct FinalAwaiter {
        bool await_ready() const noexcept { return false; }
        template <typename P> auto await_suspend(std::coroutine_handle<P> handle) noexcept {
            return handle.promise().continuation;
        }
        void await_resume() const noexcept { }
    };

    struct Promise {
        std::coroutine_handle<> continuation;
        Task get_return_object() {
            return Task { std::coroutine_handle<Promise>::from_promise(*this) };
        }
 void unhandled_exception() noexcept { }
        void return_void() noexcept { }
        std::suspend_always initial_suspend() noexcept { return {}; }
 FinalAwaiter final_suspend() noexcept { return {}; }
    };
    using promise_type = Promise;

    Task() = default;
    ~Task() { if (handle_) { handle_.destroy(); } }

    struct Awaiter {
 std::coroutine_handle<Promise> handle;
        bool await_ready() const noexcept { return !handle || handle.done(); }
        auto await_suspend(std::coroutine_handle<> calling) noexcept {
 handle.promise().continuation = calling;
            return handle;
 }
        void await_resume() const noexcept { }
    };

    auto operator co_await() noexcept { return Awaiter{handle_}; }
    void run() {
 handle_.promise().continuation = std::noop_coroutine();
 handle_.resume();
    }

private:
    explicit Task(std::coroutine_handle<Promise> handle) : handle_(handle) { }
 std::coroutine_handle<Promise> handle_;
};
// End of boilerplate.

// loosely based on std::variant<int, __int128>
struct Alt1 { __int128 i; };
struct Union : public Alt1 { };
struct Base {
  Union u;
  char idx;
};
struct Impl : public Base {
  char c[15];
};
struct Variant : public Impl { };

// Just to put more stuff in the frame.
struct Stuff { void *p, *q; };

#pragma clang optimize off
void use(Variant& v) {}
void use2(Stuff &s) {}
#pragma clang optimize on

Task __attribute__((noinline)) foo(Stuff s, Variant v) {
  auto s2 = s;
 Variant copy_of_v = v;
  use(copy_of_v);
  use2(s2);
 co_return;
}

int main() {
  Task t = foo({}, {});
 t.run();
}
```

```
$ build/bin/clang++ -std=c++20 -O3 /tmp/a.cc -fcoro-aligned-allocation
$ gdb a.out
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
0x00005555555552a0 in foo(Stuff, Variant) [clone .resume] ()
(gdb) disas
Dump of assembler code for function _Z3foo5Stuff7Variant.resume:
   0x0000555555555290 <+0>:     push   %rbx
 0x0000555555555291 <+1>:     sub    $0x30,%rsp
   0x0000555555555295 <+5>: mov    %rdi,%rbx
   0x0000555555555298 <+8>:     movups 0x18(%rdi),%xmm0
 0x000055555555529c <+12>:    movaps %xmm0,(%rsp)
=> 0x00005555555552a0 <+16>:    movaps 0x28(%rdi),%xmm0
```

It seems the `__int128` is stored at offset `0x28` (40) in the coroutine frame, which is not a multiple of 16.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0WM2O47gRfhr2pWCDoizZPvhgt8eLzSUDTHYPuQgURdnMUqRCUh73HvLsAX8ky57umUyCGA2MZbG-qvrql0OtFWfF-Q4VB1QcX-jgLtrs_ux0w7uXWjdvu9-sUGdgkqozIicpr53_R9QMkQMiB6AOLpw2gMgGb7dluS0xK7ek5mVeZ1uyWm34hpG6rFte0yZneb1BZIvyPcLhr8TpD-8RyYVicmg4oPyVaaMHJxRH-ad0lpwQOcFBC8lNL6njUFPLG9AKLs711qOGM-7C7UXzjv7BzbLhiJx6bZ1F5PTG3YIq7S7cLFjfLyYtCzc4bQSVCO-ZpNbC36j9A9D6gPC-H2opWDQaAMA6MzAHJ6Go3H-lwnGTTkL61FpLoP5VZTht3hDxbgPTyjpQmt8Y752XAcPdYBS0VFqO8gOg9XGG43gXPUX5q3vruaIdh88o_wR0cDppsIPtuWoQ2VjXeCvz_eRXdaGqkRzlr0EqPZHtgxEzhf6TTIpnl73RnbA8erBkWjmhBuqEViifSz4aftWimQiwQ8c_ZuAu6L8FzEeeP0cLniz9nq_e1Y8tDZE9c2-Zd7TS9T84c8nAD-kY8-G7ipOpPmfDkdborpozuHcXYaOe47v8BeIGFRGbKvLkXYjmfcDcRHlyyX__scTkScqgisqv9M2CUMIJKmeJ9Q1QIsWzFRwZkR9qovUP_w3KPBf8wxC6UOKx8oUAKD_CxPYsZ3yYxlDmR2h4Swfp7lD_mh9YH0C0vndFuqvxx_S4bLh1RqfqTfYlGx9T9KkL_GcpMlZj_j91DkSyiANo_YrWr2PdNlrxB8NnSn66eYSColIKPwa-bR4_bBUhFiNA_t2Gk17_H9pJ8Fr33FCnDTBdBcDv5GWKKlofxvx4ztJYc4N6bB5j-vyAj4lwpXVf3QfeGLQ51NzrO4FTKvZGXKnj9xHFb70UTLixHn4uI0PxTMqn-hjLI_n_U5hVCsUUkzjNP6kGdAv1fagvH6a91Npy-Xaf9JPSKzWCKofyV6EcIq9QVUK5jGziwjAWpnRZsHl8C2KMYDAjHftNxaDsIc76u9zzyQOdTaIoNowBYRdqQDS3J1eT5K9dL-cqHpCCKEPFIStQcXwf4Pfo8RwjYs7NvFP3l8E6cBr6wUGnDQfrhrYFocBdOLSGdoHrBP4lvPRQIacR2feeVET2_3wgLC5qvaHnjsa9EHTvRCf-5KDbFuF9nGAh7ZPFiJRwHesj5M54hiCySZpJaR-OfKxFRTPCQK4q6pwR9eB4VYXy2CgtlAx1tPWArdaTEutdGmm8zsd96A2WxLpM8RwPMt2_VbqtruHtdYx2dHF6OSvM5Jgl99-YTtvGPbTBCaEcdFQ8NZC4bLigL9qfaPERSd9GZLec-s8D9nyzfl60V1APQjaInGqv-pT2-7DRL0KFHdOCTzAs_pqDX6q7HpETXTIGi9ZX_IJKf3toFlRKzeKeFcHPTQ10qQcXnjfnpva-GYT3n40-G9qB4YyLK2_AX0CohC-__vLl0y-_e_--8HPHlYttMgxvn6X4hjHGxfghFPtEnsV2FtlAZHFgUisOY-csjpBImtvUCEstwvvj0PW-D1FreVdL7sdDw6HVBtpBsWBL9fe81boI2tZJ1Yg-9t1nM7fYb-6IHHBcCcMw6wd78c2bFKa-eblvpLIklc2k7FCHlk9W-JZjRF69vO0_0FskhCIhdPoKSWcjknBU_o7wJglvZuo7fR16C_iWbQKPEWcboW5dh991hI2OkDtUp6-0tzCKeYBN8iVGJz_6sfFOxBNW-Q0WvpGPrXqqhF8dWM47G7ogKvE0NkoMwoJ12vDG32t121ru_JEAX2KfQCvs0yb10GnuxW7qU_DrRbCLx1HaAYVukE700rdGyMrlS7PLm22-pS98l62LDcEEl_nLZVeusgYX26bIaJHXpOU15qymtGyzosSseBE7gkmBt9kmy8l6lS8LktV5wQgrt5tNS0q0wryjQi79HX2pzflFWDvwXVZsi3X2ImnNpQ0XfUImuy0ixF_8zc5LLerhbNEKS2GdveM44STfMUPtxQ9gqWkY2YNquBl7AAg_Wv1t55mUl8HI3eP1_CzcZaiXTHez_1Lw-nuj403sFGz3F_Zk_nVH_h0AAP__Zgjt8g">