From 18b9c23f2d4e15e1a775199da0cdd18718eb61a0 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 19 Sep 2025 13:47:10 +0200 Subject: [PATCH 1/2] [Coroutines] Take byval param alignment into account when spilling to frame Fixes #159571 --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 10 +++++++--- llvm/test/Transforms/Coroutines/coro-byval-param.ll | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 08f03aa45255d..d5becd8cedbdd 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -907,12 +907,16 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape, // Create an entry for every spilled value. for (auto &S : FrameData.Spills) { Type *FieldType = S.first->getType(); + MaybeAlign MA; // For byval arguments, we need to store the pointed value in the frame, // instead of the pointer itself. - if (const Argument *A = dyn_cast(S.first)) - if (A->hasByValAttr()) + if (const Argument *A = dyn_cast(S.first)) { + if (A->hasByValAttr()) { FieldType = A->getParamByValType(); - FieldIDType Id = B.addField(FieldType, std::nullopt, false /*header*/, + MA = A->getParamAlign(); + } + } + FieldIDType Id = B.addField(FieldType, MA, false /*header*/, true /*IsSpillOfValue*/); FrameData.setFieldIndex(S.first, Id); } diff --git a/llvm/test/Transforms/Coroutines/coro-byval-param.ll b/llvm/test/Transforms/Coroutines/coro-byval-param.ll index 38ab5ac481cd9..864b7cae9ca5e 100644 --- a/llvm/test/Transforms/Coroutines/coro-byval-param.ll +++ b/llvm/test/Transforms/Coroutines/coro-byval-param.ll @@ -56,8 +56,9 @@ coro.ret: ; preds = %coro.free, %cleanup ret ptr %call2 } -; check that the frame contains the entire struct, instead of just the struct pointer -; CHECK: %foo.Frame = type { ptr, ptr, %promise_type, %struct.A, i1 } +; check that the frame contains the entire struct, instead of just the struct pointer, +; and that the alignment is taken into account. +; CHECK: %foo.Frame = type { ptr, ptr, %promise_type, i1, [6 x i8], %struct.A } ; Function Attrs: argmemonly nounwind readonly declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 From 67cca48ac3d5e3ff54981f3a5b7e192bedf6f835 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 19 Sep 2025 14:13:46 +0200 Subject: [PATCH 2/2] format --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index d5becd8cedbdd..0accb225122be 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -916,8 +916,8 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape, MA = A->getParamAlign(); } } - FieldIDType Id = B.addField(FieldType, MA, false /*header*/, - true /*IsSpillOfValue*/); + FieldIDType Id = + B.addField(FieldType, MA, false /*header*/, true /*IsSpillOfValue*/); FrameData.setFieldIndex(S.first, Id); }