|
3 | 3 | // Vefifies that parameter copies are used in the body of the coroutine |
4 | 4 | // Verifies that parameter copies are used to construct the promise type, if that type has a matching constructor |
5 | 5 | // RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -disable-llvm-passes -fexceptions | FileCheck %s |
| 6 | +// RUN: %clang_cc1 -std=c++20 -triple=x86_64-pc-win32 -emit-llvm -o - %s -disable-llvm-passes -fexceptions | FileCheck %s --check-prefix=MSABI |
6 | 7 |
|
7 | 8 | namespace std { |
8 | 9 | template <typename... T> struct coroutine_traits; |
@@ -209,3 +210,37 @@ method some_class::good_coroutine_calls_custom_constructor(float) { |
209 | 210 | // CHECK: invoke void @_ZNSt16coroutine_traitsIJ6methodR10some_classfEE12promise_typeC1ES2_f(ptr {{[^,]*}} %__promise, ptr noundef nonnull align 1 dereferenceable(1) %{{.+}}, float |
210 | 211 | co_return; |
211 | 212 | } |
| 213 | + |
| 214 | + |
| 215 | +struct MSParm { |
| 216 | + int val; |
| 217 | + ~MSParm(); |
| 218 | +}; |
| 219 | + |
| 220 | +void consume(int) noexcept; |
| 221 | + |
| 222 | +// Similarly to the [[clang::trivial_abi]] parameters, with the MSVC ABI |
| 223 | +// parameters are also destroyed by the callee, and on x86-64 such parameters |
| 224 | +// may get passed in registers. In that case it's again important that the |
| 225 | +// parameter's local alloca does not become part of the coro frame since that |
| 226 | +// may be destroyed before the destructor call. |
| 227 | +void msabi(MSParm p) { |
| 228 | + // MSABI: define{{.*}} void @"?msabi@@YAXUMSParm@@@Z"(i32 %[[Param:.+]]) |
| 229 | + // MSABI: %[[ParamAlloca:.+]] = alloca %struct.MSParm |
| 230 | + // MSABI: %[[ParamCopy:.+]] = alloca %struct.MSParm |
| 231 | + |
| 232 | + // The parameter's local alloca is marked not part of the frame. |
| 233 | + // MSABI: call void @llvm.coro.outside.frame(ptr %[[ParamAlloca]]) |
| 234 | + |
| 235 | + consume(p.val); |
| 236 | + // The parameter's copy is used by the coroutine. |
| 237 | + // MSABI: %[[ValPtr:.+]] = getelementptr inbounds nuw %struct.MSParm, ptr %[[ParamCopy]], i32 0, i32 0 |
| 238 | + // MSABI: %[[Val:.+]] = load i32, ptr %[[ValPtr]] |
| 239 | + // MSABI: call void @"?consume@@YAXH@Z"(i32{{.*}} %[[Val]]) |
| 240 | + |
| 241 | + co_return; |
| 242 | + |
| 243 | + // The local alloca is used for the destructor call at the end of the ramp. |
| 244 | + // MSABI: call i1 @llvm.coro.end |
| 245 | + // MSABI: call void @"??1MSParm@@QEAA@XZ"(ptr{{.*}} %[[ParamAlloca]]) |
| 246 | +} |
0 commit comments