[llvm] [Coroutines] Take byval param alignment into account when spilling to frame (PR #159765)

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 19 05:14:03 PDT 2025


https://github.com/zmodem updated https://github.com/llvm/llvm-project/pull/159765

>From 18b9c23f2d4e15e1a775199da0cdd18718eb61a0 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
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<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

>From 67cca48ac3d5e3ff54981f3a5b7e192bedf6f835 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
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);
   }
 



More information about the llvm-commits mailing list