Skip to content

Conversation

zmodem
Copy link
Collaborator

@zmodem zmodem commented Sep 19, 2025

Fixes #159571

@zmodem zmodem added the coroutines C++20 coroutines label Sep 19, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 19, 2025

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-coroutines

Author: Hans Wennborg (zmodem)

Changes

Fixes #159571


Full diff: https://github.com/llvm/llvm-project/pull/159765.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Coroutines/CoroFrame.cpp (+7-3)
  • (modified) llvm/test/Transforms/Coroutines/coro-byval-param.ll (+3-2)
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<Argument>(S.first))
-      if (A->hasByValAttr())
+    if (const Argument *A = dyn_cast<Argument>(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

Copy link

github-actions bot commented Sep 19, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@NewSigma NewSigma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, please wait a few days in case other reviewers might wish to have a look.

@zmodem zmodem merged commit cc6b81c into llvm:main Sep 22, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

crash on load of under-aligned i128 from coroutine frame
4 participants