[clang] [llvm] [Coroutines] Replace struct alloca frame with byte array and ptradd (PR #178359)
Jameson Nash via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 16 08:56:47 PST 2026
https://github.com/vtjnash updated https://github.com/llvm/llvm-project/pull/178359
>From 9fc6a1afb4c9d943e79a7739c13757eba5e46fd6 Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash at gmail.com>
Date: Fri, 13 Feb 2026 22:14:35 +0000
Subject: [PATCH 1/2] [Coroutines] Replace struct alloca frame with byte array
and ptradd
Replace coroutine frame struct type with a simple byte array and use
offset-based ptradd operations instead of struct GEP for all field
access. Alloca types have largely lost all meaning to LLVM (even this
pass merges them and uses a random type to represent all of them), and
so they just makes the code to construct alloca more difficult and less
flexible.
Key changes:
- Remove LayoutFieldIndex from frame field tracking
- Remove StructType usage - frame is now a byte array
- Replace all CreateStructGEP/CreateConstInBoundsGEP with CreatePtrAdd
- Store ResumeOffset/DestroyOffset in SwitchLowering for reuse
- Remove Shape.FrameTy, use Shape.FrameSize directly
Bug fix: Uses pointer size and alignment from data layout for header
pointer offsets in debug info instead of hardcoded 8 byte.
Optimization: Replaces load+store patterns with CreateMemCpy for copying
allocas to the frame more efficiently.
Optimization: Add missing inbounds annotations on existing ptradd calls.
Improvement: Preserve debug info of every alloca, even overlapping ones.
The frame type is now completely opaque at the IR level. All structure
is implicit through computed offsets. Debug info still provides detailed
field information using explicit offsets.
Co-Authored-By: Claude Opus 4.5 <noreply at anthropic.com>
---
.../coro-suspend-cleanups.cpp | 4 +-
.../llvm/Transforms/Coroutines/CoroShape.h | 23 +-
llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 439 ++++++++----------
llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 101 ++--
llvm/test/Transforms/Coroutines/ArgAddr.ll | 11 +-
.../Transforms/Coroutines/coro-align16.ll | 9 +-
.../Transforms/Coroutines/coro-align32.ll | 9 +-
.../Transforms/Coroutines/coro-align64-02.ll | 9 +-
.../Transforms/Coroutines/coro-align64.ll | 9 +-
.../Transforms/Coroutines/coro-align8-02.ll | 7 +-
.../test/Transforms/Coroutines/coro-align8.ll | 7 +-
.../Coroutines/coro-alloc-with-param-O0.ll | 8 +-
.../Coroutines/coro-alloc-with-param-O2.ll | 8 +-
.../Transforms/Coroutines/coro-alloca-01.ll | 13 +-
.../Transforms/Coroutines/coro-alloca-02.ll | 11 +-
.../Transforms/Coroutines/coro-alloca-03.ll | 9 +-
.../Transforms/Coroutines/coro-alloca-04.ll | 11 +-
.../Transforms/Coroutines/coro-alloca-06.ll | 7 +-
.../Transforms/Coroutines/coro-alloca-07.ll | 12 +-
.../Transforms/Coroutines/coro-alloca-08.ll | 12 +-
.../Transforms/Coroutines/coro-alloca-09.ll | 12 +-
.../coro-alloca-loop-carried-address.ll | 8 +-
.../Coroutines/coro-alloca-with-addrspace.ll | 10 +-
.../Coroutines/coro-async-dyn-align.ll | 15 +-
.../coro-await-suspend-lower-invoke.ll | 23 +-
.../Coroutines/coro-await-suspend-lower.ll | 23 +-
.../Transforms/Coroutines/coro-byval-param.ll | 16 +-
.../Transforms/Coroutines/coro-catchswitch.ll | 6 +-
.../Coroutines/coro-eh-aware-edge-split-01.ll | 16 +-
.../Coroutines/coro-eh-aware-edge-split-02.ll | 16 +-
.../Coroutines/coro-frame-arrayalloca.ll | 16 +-
.../Coroutines/coro-frame-reuse-alloca-01.ll | 11 +-
.../Coroutines/coro-frame-reuse-alloca-02.ll | 11 +-
.../Coroutines/coro-frame-reuse-alloca-04.ll | 13 +-
.../Coroutines/coro-frame-reuse-alloca-05.ll | 11 +-
llvm/test/Transforms/Coroutines/coro-frame.ll | 12 +-
.../Coroutines/coro-lifetime-end.ll | 18 +-
llvm/test/Transforms/Coroutines/coro-noop.ll | 1 -
.../Transforms/Coroutines/coro-padding.ll | 10 +-
.../Transforms/Coroutines/coro-param-copy.ll | 19 +-
.../Coroutines/coro-retcon-once-value.ll | 2 +-
.../Coroutines/coro-retcon-once-value2.ll | 22 +-
.../Coroutines/coro-retcon-remat.ll | 6 +-
.../Coroutines/coro-retcon-resume-values2.ll | 18 +-
.../test/Transforms/Coroutines/coro-retcon.ll | 8 +-
.../Coroutines/coro-spill-after-phi.ll | 9 +-
.../Coroutines/coro-spill-corobegin.ll | 8 +-
.../coro-spill-defs-before-corobegin.ll | 11 +-
.../Coroutines/coro-spill-promise-02.ll | 15 +-
.../Coroutines/coro-spill-promise.ll | 10 +-
.../Coroutines/coro-spill-suspend.ll | 26 +-
.../coro-split-dbg-nested-struct.ll | 2 +
.../Coroutines/coro-split-tbaa-md.ll | 12 +-
.../Transforms/Coroutines/coro-zero-alloca.ll | 8 +-
54 files changed, 546 insertions(+), 597 deletions(-)
diff --git a/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp b/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp
index d71c2c558996a..77abc53ce2e71 100644
--- a/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp
+++ b/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp
@@ -47,7 +47,7 @@ coroutine ArrayInitCoro() {
// CHECK-NEXT: store ptr %arr.reload.addr, ptr %arrayinit.endOfInit.reload.addr, align 8
// CHECK-NEXT: call void @_ZN6PrintyC1EPKc(ptr noundef nonnull align 8 dereferenceable(8) %arr.reload.addr, ptr noundef @.str)
// CHECK-NEXT: %arrayinit.element = getelementptr inbounds %struct.Printy, ptr %arr.reload.addr, i64 1
- // CHECK-NEXT: %arrayinit.element.spill.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 10
+ // CHECK-NEXT: %arrayinit.element.spill.addr = getelementptr inbounds i8, ptr %0, i64 48
// CHECK-NEXT: store ptr %arrayinit.element, ptr %arrayinit.element.spill.addr, align 8
// CHECK-NEXT: store ptr %arrayinit.element, ptr %arrayinit.endOfInit.reload.addr, align 8
co_await Awaiter{}
@@ -61,7 +61,7 @@ coroutine ArrayInitCoro() {
// CHECK: br label %cleanup{{.*}}
// CHECK: await.ready:
- // CHECK-NEXT: %arrayinit.element.reload.addr = getelementptr inbounds %_Z13ArrayInitCorov.Frame, ptr %0, i32 0, i32 10
+ // CHECK-NEXT: %arrayinit.element.reload.addr = getelementptr inbounds i8, ptr %0, i64 48
// CHECK-NEXT: %arrayinit.element.reload = load ptr, ptr %arrayinit.element.reload.addr, align 8
// CHECK-NEXT: call void @_ZN7Awaiter12await_resumeEv
// CHECK-NEXT: store i1 false, ptr %cleanup.isactive.reload.addr, align 1
diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
index 11b004572957f..88ae4dc306be2 100644
--- a/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
+++ b/llvm/include/llvm/Transforms/Coroutines/CoroShape.h
@@ -75,7 +75,6 @@ struct Shape {
SwiftErrorOps.clear();
- FrameTy = nullptr;
FramePtr = nullptr;
AllocaSpillBlock = nullptr;
}
@@ -113,7 +112,6 @@ struct Shape {
coro::ABI ABI;
- StructType *FrameTy = nullptr;
Align FrameAlign;
uint64_t FrameSize = 0;
Value *FramePtr = nullptr;
@@ -123,7 +121,9 @@ struct Shape {
SwitchInst *ResumeSwitch;
AllocaInst *PromiseAlloca;
BasicBlock *ResumeEntryBlock;
- unsigned IndexField;
+ IntegerType *IndexType;
+ unsigned ResumeOffset;
+ unsigned DestroyOffset;
unsigned IndexAlign;
unsigned IndexOffset;
bool HasFinalSuspend;
@@ -172,15 +172,10 @@ struct Shape {
return cast<CoroIdAsyncInst>(CoroBegin->getId());
}
- unsigned getSwitchIndexField() const {
- assert(ABI == coro::ABI::Switch);
- assert(FrameTy && "frame type not assigned");
- return SwitchLowering.IndexField;
- }
IntegerType *getIndexType() const {
assert(ABI == coro::ABI::Switch);
- assert(FrameTy && "frame type not assigned");
- return cast<IntegerType>(FrameTy->getElementType(getSwitchIndexField()));
+ assert(SwitchLowering.IndexType && "index type not assigned");
+ return SwitchLowering.IndexType;
}
ConstantInt *getIndex(uint64_t Value) const {
return ConstantInt::get(getIndexType(), Value);
@@ -188,15 +183,15 @@ struct Shape {
PointerType *getSwitchResumePointerType() const {
assert(ABI == coro::ABI::Switch);
- assert(FrameTy && "frame type not assigned");
- return cast<PointerType>(FrameTy->getElementType(SwitchFieldIndex::Resume));
+ assert(CoroBegin && "CoroBegin not assigned");
+ return PointerType::getUnqual(CoroBegin->getContext());
}
FunctionType *getResumeFunctionType() const {
switch (ABI) {
case coro::ABI::Switch:
- return FunctionType::get(Type::getVoidTy(FrameTy->getContext()),
- PointerType::getUnqual(FrameTy->getContext()),
+ return FunctionType::get(Type::getVoidTy(CoroBegin->getContext()),
+ PointerType::getUnqual(CoroBegin->getContext()),
/*IsVarArg=*/false);
case coro::ABI::Retcon:
case coro::ABI::RetconOnce:
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 2f2ef7f9eee2c..01bf6ac22790e 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -77,7 +77,7 @@ struct FrameDataInfo {
}
void setFieldIndex(Value *V, uint32_t Index) {
- assert((LayoutIndexUpdateStarted || FieldIndexMap.count(V) == 0) &&
+ assert(FieldIndexMap.count(V) == 0 &&
"Cannot set the index for the same field twice.");
FieldIndexMap[V] = Index;
}
@@ -115,16 +115,11 @@ struct FrameDataInfo {
FieldOffsetMap.insert({V, Offset});
}
- // Remap the index of every field in the frame, using the final layout index.
- void updateLayoutIndex(FrameTypeBuilder &B);
+ // Update field offset and alignment information from FrameTypeBuilder.
+ void updateLayoutInfo(FrameTypeBuilder &B);
private:
- // LayoutIndexUpdateStarted is used to avoid updating the index of any field
- // twice by mistake.
- bool LayoutIndexUpdateStarted = false;
- // Map from values to their slot indexes on the frame. They will be first set
- // with their original insertion field index. After the frame is built, their
- // indexes will be updated into the final layout index.
+ // Map from values to their slot indexes on the frame (insertion order).
DenseMap<Value *, uint32_t> FieldIndexMap;
// Map from values to their alignment on the frame. They would be set after
// the frame is built.
@@ -166,10 +161,7 @@ class FrameTypeBuilder {
struct Field {
uint64_t Size;
uint64_t Offset;
- Type *Ty;
- FieldIDType LayoutFieldIndex;
Align Alignment;
- Align TyAlignment;
uint64_t DynamicAlignBuffer;
};
@@ -184,6 +176,8 @@ class FrameTypeBuilder {
SmallVector<Field, 8> Fields;
DenseMap<Value*, unsigned> FieldIndexByKey;
+ IntegerType *SwitchIndexType = nullptr;
+
public:
FrameTypeBuilder(LLVMContext &Context, const DataLayout &DL,
std::optional<Align> MaxFrameAlignment)
@@ -193,17 +187,11 @@ class FrameTypeBuilder {
/// instruction.
[[nodiscard]] FieldIDType addFieldForAlloca(AllocaInst *AI,
bool IsHeader = false) {
- Type *Ty = AI->getAllocatedType();
-
- // Make an array type if this is a static array allocation.
- if (AI->isArrayAllocation()) {
- if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
- Ty = ArrayType::get(Ty, CI->getValue().getZExtValue());
- else
- report_fatal_error("Coroutines cannot handle non static allocas yet");
- }
-
- return addField(Ty, AI->getAlign(), IsHeader);
+ auto Size = AI->getAllocationSize(AI->getDataLayout());
+ if (!Size || !Size->isFixed())
+ report_fatal_error(
+ "Coroutines cannot handle non static or vscale allocas yet");
+ return addField(Size->getFixedValue(), AI->getAlign(), IsHeader);
}
/// We want to put the allocas whose lifetime-ranges are not overlapped
@@ -236,31 +224,33 @@ class FrameTypeBuilder {
void addFieldForAllocas(const Function &F, FrameDataInfo &FrameData,
coro::Shape &Shape, bool OptimizeFrame);
- /// Add a field to this structure.
+ /// Add a field to this structure for a spill.
[[nodiscard]] FieldIDType addField(Type *Ty, MaybeAlign MaybeFieldAlignment,
bool IsHeader = false,
bool IsSpillOfValue = false) {
- assert(!IsFinished && "adding fields to a finished builder");
assert(Ty && "must provide a type for a field");
-
- // The field size is always the alloc size of the type.
+ // The field size is the alloc size of the type.
uint64_t FieldSize = DL.getTypeAllocSize(Ty);
-
- // For an alloca with size=0, we don't need to add a field and they
- // can just point to any index in the frame. Use index 0.
- if (FieldSize == 0) {
- return 0;
- }
-
- // The field alignment might not be the type alignment, but we need
- // to remember the type alignment anyway to build the type.
- // If we are spilling values we don't need to worry about ABI alignment
+ // The field alignment is usually the type alignment.
+ // But if we are spilling values we don't need to worry about ABI alignment
// concerns.
Align ABIAlign = DL.getABITypeAlign(Ty);
Align TyAlignment = ABIAlign;
if (IsSpillOfValue && MaxFrameAlignment && *MaxFrameAlignment < ABIAlign)
TyAlignment = *MaxFrameAlignment;
Align FieldAlignment = MaybeFieldAlignment.value_or(TyAlignment);
+ return addField(FieldSize, FieldAlignment, IsHeader);
+ }
+
+ /// Add a field to this structure.
+ [[nodiscard]] FieldIDType addField(uint64_t FieldSize, Align FieldAlignment,
+ bool IsHeader = false) {
+ assert(!IsFinished && "adding fields to a finished builder");
+
+ // For an alloca with size=0, we don't need to add a field and they
+ // can just point to any index in the frame. Use index 0.
+ if (FieldSize == 0)
+ return 0;
// The field alignment could be bigger than the max frame case, in that case
// we request additional storage to be able to dynamically align the
@@ -284,13 +274,12 @@ class FrameTypeBuilder {
Offset = OptimizedStructLayoutField::FlexibleOffset;
}
- Fields.push_back({FieldSize, Offset, Ty, 0, FieldAlignment, TyAlignment,
- DynamicAlignBuffer});
+ Fields.push_back({FieldSize, Offset, FieldAlignment, DynamicAlignBuffer});
return Fields.size() - 1;
}
- /// Finish the layout and create the struct type with the given name.
- StructType *finish(StringRef Name);
+ /// Finish the layout and compute final size and alignment.
+ void finish(StringRef Name);
uint64_t getStructSize() const {
assert(IsFinished && "not yet finished!");
@@ -302,22 +291,21 @@ class FrameTypeBuilder {
return StructAlign;
}
- FieldIDType getLayoutFieldIndex(FieldIDType Id) const {
- assert(IsFinished && "not yet finished!");
- return Fields[Id].LayoutFieldIndex;
- }
-
Field getLayoutField(FieldIDType Id) const {
assert(IsFinished && "not yet finished!");
return Fields[Id];
}
+
+ void setSwitchIndexType(IntegerType *Ty) { SwitchIndexType = Ty; }
+
+ IntegerType *getSwitchIndexType() const { return SwitchIndexType; }
};
} // namespace
-void FrameDataInfo::updateLayoutIndex(FrameTypeBuilder &B) {
+void FrameDataInfo::updateLayoutInfo(FrameTypeBuilder &B) {
auto Updater = [&](Value *I) {
- auto Field = B.getLayoutField(getFieldIndex(I));
- setFieldIndex(I, Field.LayoutFieldIndex);
+ uint32_t FieldIndex = getFieldIndex(I);
+ auto Field = B.getLayoutField(FieldIndex);
setAlign(I, Field.Alignment);
uint64_t dynamicAlign =
Field.DynamicAlignBuffer
@@ -326,12 +314,10 @@ void FrameDataInfo::updateLayoutIndex(FrameTypeBuilder &B) {
setDynamicAlign(I, dynamicAlign);
setOffset(I, Field.Offset);
};
- LayoutIndexUpdateStarted = true;
for (auto &S : Spills)
Updater(S.first);
for (const auto &A : Allocas)
Updater(A.Alloca);
- LayoutIndexUpdateStarted = false;
}
void FrameTypeBuilder::addFieldForAllocas(const Function &F,
@@ -463,7 +449,7 @@ void FrameTypeBuilder::addFieldForAllocas(const Function &F,
});
}
-StructType *FrameTypeBuilder::finish(StringRef Name) {
+void FrameTypeBuilder::finish(StringRef Name) {
assert(!IsFinished && "already finished!");
// Prepare the optimal-layout field array.
@@ -475,7 +461,7 @@ StructType *FrameTypeBuilder::finish(StringRef Name) {
Field.Offset);
}
- // Perform layout.
+ // Perform layout to compute size, alignment, and field offsets.
auto SizeAndAlign = performOptimizedStructLayout(LayoutFields);
StructSize = SizeAndAlign.first;
StructAlign = SizeAndAlign.second;
@@ -484,61 +470,13 @@ StructType *FrameTypeBuilder::finish(StringRef Name) {
return *static_cast<Field *>(const_cast<void*>(LayoutField.Id));
};
- // We need to produce a packed struct type if there's a field whose
- // assigned offset isn't a multiple of its natural type alignment.
- bool Packed = [&] {
- for (auto &LayoutField : LayoutFields) {
- auto &F = getField(LayoutField);
- if (!isAligned(F.TyAlignment, LayoutField.Offset))
- return true;
- }
- return false;
- }();
-
- // Build the struct body.
- SmallVector<Type*, 16> FieldTypes;
- FieldTypes.reserve(LayoutFields.size() * 3 / 2);
- uint64_t LastOffset = 0;
+ // Update field offsets from the computed layout.
for (auto &LayoutField : LayoutFields) {
auto &F = getField(LayoutField);
-
- auto Offset = LayoutField.Offset;
-
- // Add a padding field if there's a padding gap and we're either
- // building a packed struct or the padding gap is more than we'd
- // get from aligning to the field type's natural alignment.
- assert(Offset >= LastOffset);
- if (Offset != LastOffset) {
- if (Packed || alignTo(LastOffset, F.TyAlignment) != Offset)
- FieldTypes.push_back(ArrayType::get(Type::getInt8Ty(Context),
- Offset - LastOffset));
- }
-
- F.Offset = Offset;
- F.LayoutFieldIndex = FieldTypes.size();
-
- FieldTypes.push_back(F.Ty);
- if (F.DynamicAlignBuffer) {
- FieldTypes.push_back(
- ArrayType::get(Type::getInt8Ty(Context), F.DynamicAlignBuffer));
- }
- LastOffset = Offset + F.Size;
- }
-
- StructType *Ty = StructType::create(Context, FieldTypes, Name, Packed);
-
-#ifndef NDEBUG
- // Check that the IR layout matches the offsets we expect.
- auto Layout = DL.getStructLayout(Ty);
- for (auto &F : Fields) {
- assert(Ty->getElementType(F.LayoutFieldIndex) == F.Ty);
- assert(Layout->getElementOffset(F.LayoutFieldIndex) == F.Offset);
+ F.Offset = LayoutField.Offset;
}
-#endif
IsFinished = true;
-
- return Ty;
}
static void cacheDIVar(FrameDataInfo &FrameData,
@@ -710,112 +648,96 @@ static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
unsigned LineNum = DIS->getLine();
DICompositeType *FrameDITy = DBuilder.createStructType(
- DIS->getUnit(), Twine(F.getName() + ".coro_frame_ty").str(),
- DFile, LineNum, Shape.FrameSize * 8,
- Shape.FrameAlign.value() * 8, llvm::DINode::FlagArtificial, nullptr,
- llvm::DINodeArray());
- StructType *FrameTy = Shape.FrameTy;
+ DIS->getUnit(), Twine(F.getName() + ".coro_frame_ty").str(), DFile,
+ LineNum, Shape.FrameSize * 8, Shape.FrameAlign.value() * 8,
+ llvm::DINode::FlagArtificial, nullptr, llvm::DINodeArray());
SmallVector<Metadata *, 16> Elements;
DataLayout Layout = F.getDataLayout();
DenseMap<Value *, DILocalVariable *> DIVarCache;
cacheDIVar(FrameData, DIVarCache);
- unsigned ResumeIndex = coro::Shape::SwitchFieldIndex::Resume;
- unsigned DestroyIndex = coro::Shape::SwitchFieldIndex::Destroy;
- unsigned IndexIndex = Shape.SwitchLowering.IndexField;
-
- DenseMap<unsigned, StringRef> NameCache;
- NameCache.insert({ResumeIndex, "__resume_fn"});
- NameCache.insert({DestroyIndex, "__destroy_fn"});
- NameCache.insert({IndexIndex, "__coro_index"});
-
- Type *ResumeFnTy = FrameTy->getElementType(ResumeIndex),
- *DestroyFnTy = FrameTy->getElementType(DestroyIndex),
- *IndexTy = FrameTy->getElementType(IndexIndex);
-
- DenseMap<unsigned, DIType *> TyCache;
- TyCache.insert(
- {ResumeIndex, DBuilder.createPointerType(
- nullptr, Layout.getTypeSizeInBits(ResumeFnTy))});
- TyCache.insert(
- {DestroyIndex, DBuilder.createPointerType(
- nullptr, Layout.getTypeSizeInBits(DestroyFnTy))});
-
- /// FIXME: If we fill the field `SizeInBits` with the actual size of
- /// __coro_index in bits, then __coro_index wouldn't show in the debugger.
- TyCache.insert({IndexIndex, DBuilder.createBasicType(
- "__coro_index",
- (Layout.getTypeSizeInBits(IndexTy) < 8)
- ? 8
- : Layout.getTypeSizeInBits(IndexTy),
- dwarf::DW_ATE_unsigned_char)});
-
- for (auto *V : FrameData.getAllDefs()) {
- auto It = DIVarCache.find(V);
- if (It == DIVarCache.end())
- continue;
-
- auto Index = FrameData.getFieldIndex(V);
-
- NameCache.insert({Index, It->second->getName()});
- TyCache.insert({Index, It->second->getType()});
- }
-
- // Cache from index to (Align, Offset Pair)
- DenseMap<unsigned, std::pair<unsigned, unsigned>> OffsetCache;
- // The Align and Offset of Resume function and Destroy function are fixed.
- OffsetCache.insert({ResumeIndex, {8, 0}});
- OffsetCache.insert({DestroyIndex, {8, 8}});
- OffsetCache.insert(
- {IndexIndex,
- {Shape.SwitchLowering.IndexAlign, Shape.SwitchLowering.IndexOffset}});
-
- for (auto *V : FrameData.getAllDefs()) {
- auto Index = FrameData.getFieldIndex(V);
-
- OffsetCache.insert(
- {Index, {FrameData.getAlign(V).value(), FrameData.getOffset(V)}});
- }
-
- DenseMap<Type *, DIType *> DITypeCache;
// This counter is used to avoid same type names. e.g., there would be
// many i32 and i64 types in one coroutine. And we would use i32_0 and
// i32_1 to avoid the same type. Since it makes no sense the name of the
// fields confilicts with each other.
unsigned UnknownTypeNum = 0;
- for (unsigned Index = 0; Index < FrameTy->getNumElements(); Index++) {
- auto OCIt = OffsetCache.find(Index);
- if (OCIt == OffsetCache.end())
- continue;
+ DenseMap<Type *, DIType *> DITypeCache;
+
+ auto addElement = [&](StringRef Name, uint64_t SizeInBits, uint64_t Alignment,
+ uint64_t Offset, DIType *DITy) {
+ Elements.push_back(DBuilder.createMemberType(
+ FrameDITy, Name, DFile, LineNum, SizeInBits, Alignment, Offset * 8,
+ llvm::DINode::FlagArtificial, DITy));
+ };
+
+ auto addDIDef = [&](Value *V) {
+ // Get the offset and alignment for this value.
+ uint64_t Offset = FrameData.getOffset(V);
+ Align Alignment = FrameData.getAlign(V);
std::string Name;
uint64_t SizeInBits;
- uint32_t AlignInBits;
- uint64_t OffsetInBits;
DIType *DITy = nullptr;
- Type *Ty = FrameTy->getElementType(Index);
- assert(Ty->isSized() && "We can't handle type which is not sized.\n");
- SizeInBits = Layout.getTypeSizeInBits(Ty).getFixedValue();
- AlignInBits = OCIt->second.first * 8;
- OffsetInBits = OCIt->second.second * 8;
-
- if (auto It = NameCache.find(Index); It != NameCache.end()) {
- Name = It->second.str();
- DITy = TyCache[Index];
+ auto It = DIVarCache.find(V);
+ if (It != DIVarCache.end()) {
+ // Get the type from the debug variable.
+ Name = It->second->getName().str();
+ DITy = It->second->getType();
} else {
- DITy = solveDIType(DBuilder, Ty, Layout, FrameDITy, LineNum, DITypeCache);
+ if (auto AI = dyn_cast<AllocaInst>(V)) {
+ // Frame alloca
+ DITy = solveDIType(DBuilder, AI->getAllocatedType(), Layout, FrameDITy,
+ LineNum, DITypeCache);
+ } else {
+ // Spill
+ DITy = solveDIType(DBuilder, V->getType(), Layout, FrameDITy, LineNum,
+ DITypeCache);
+ }
assert(DITy && "SolveDIType shouldn't return nullptr.\n");
Name = DITy->getName().str();
Name += "_" + std::to_string(UnknownTypeNum);
UnknownTypeNum++;
}
- Elements.push_back(DBuilder.createMemberType(
- FrameDITy, Name, DFile, LineNum, SizeInBits, AlignInBits, OffsetInBits,
- llvm::DINode::FlagArtificial, DITy));
- }
+ if (auto AI = dyn_cast<AllocaInst>(V)) {
+ // Lookup the total size of this alloca originally
+ auto Size = AI->getAllocationSize(Layout);
+ assert(Size && Size->isFixed() &&
+ "unreachable due to addFieldForAlloca checks");
+ SizeInBits = Size->getFixedValue() * 8;
+ } else {
+ // Compute the size of the active data of this member for this spill
+ SizeInBits = Layout.getTypeSizeInBits(V->getType());
+ }
+
+ addElement(Name, SizeInBits, Alignment.value() * 8, Offset, DITy);
+ };
+
+ // For Switch ABI, add debug info for the added fields (resume, destroy).
+ if (Shape.ABI == coro::ABI::Switch) {
+ auto *FnPtrTy = Shape.getSwitchResumePointerType();
+ uint64_t PtrSize = Layout.getPointerSizeInBits(FnPtrTy->getAddressSpace());
+ uint64_t PtrAlign =
+ Layout.getPointerABIAlignment(FnPtrTy->getAddressSpace()).value() * 8;
+ auto *DIPtr = DBuilder.createPointerType(nullptr, PtrSize,
+ FnPtrTy->getAddressSpace());
+ addElement("__resume_fn", PtrSize, PtrAlign,
+ Shape.SwitchLowering.ResumeOffset, DIPtr);
+ addElement("__destroy_fn", PtrSize, PtrAlign,
+ Shape.SwitchLowering.DestroyOffset, DIPtr);
+ uint64_t IndexSize =
+ Layout.getTypeSizeInBits(Shape.getIndexType()).getFixedValue();
+ addElement("__coro_index", IndexSize, Shape.SwitchLowering.IndexAlign * 8,
+ Shape.SwitchLowering.IndexOffset,
+ DBuilder.createBasicType("__coro_index",
+ (IndexSize < 8) ? 8 : IndexSize,
+ dwarf::DW_ATE_unsigned_char));
+ }
+ auto Defs = FrameData.getAllDefs();
+ for (auto *V : Defs)
+ addDIDef(V);
DBuilder.replaceArrays(FrameDITy, DBuilder.getOrCreateArray(Elements));
@@ -850,17 +772,15 @@ static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
It->getParent()->insertDbgRecordBefore(NewDVR, It);
}
-// Build a struct that will keep state for an active coroutine.
-// struct f.frame {
-// ResumeFnTy ResumeFnAddr;
-// ResumeFnTy DestroyFnAddr;
-// ... promise (if present) ...
-// int ResumeIndex;
-// ... spills ...
-// };
-static StructType *buildFrameType(Function &F, coro::Shape &Shape,
- FrameDataInfo &FrameData,
- bool OptimizeFrame) {
+// Build the coroutine frame type as a byte array.
+// The frame layout includes:
+// - Resume function pointer at offset 0 (Switch ABI only)
+// - Destroy function pointer at offset ptrsize (Switch ABI only)
+// - Promise alloca (Switch ABI only, only if present)
+// - Suspend/Resume index
+// - Spilled values and allocas
+static void buildFrameLayout(Function &F, coro::Shape &Shape,
+ FrameDataInfo &FrameData, bool OptimizeFrame) {
LLVMContext &C = F.getContext();
const DataLayout &DL = F.getDataLayout();
@@ -874,12 +794,12 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
std::optional<FieldIDType> SwitchIndexFieldId;
if (Shape.ABI == coro::ABI::Switch) {
- auto *FnPtrTy = PointerType::getUnqual(C);
+ auto *FnPtrTy = Shape.getSwitchResumePointerType();
// Add header fields for the resume and destroy functions.
// We can rely on these being perfectly packed.
- (void)B.addField(FnPtrTy, std::nullopt, /*header*/ true);
- (void)B.addField(FnPtrTy, std::nullopt, /*header*/ true);
+ (void)B.addField(FnPtrTy, MaybeAlign(), /*header*/ true);
+ (void)B.addField(FnPtrTy, MaybeAlign(), /*header*/ true);
// PromiseAlloca field needs to be explicitly added here because it's
// a header field with a fixed offset based on its alignment. Hence it
@@ -891,9 +811,10 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
// Add a field to store the suspend index. This doesn't need to
// be in the header.
unsigned IndexBits = std::max(1U, Log2_64_Ceil(Shape.CoroSuspends.size()));
- Type *IndexType = Type::getIntNTy(C, IndexBits);
+ IntegerType *IndexType = Type::getIntNTy(C, IndexBits);
- SwitchIndexFieldId = B.addField(IndexType, std::nullopt);
+ SwitchIndexFieldId = B.addField(IndexType, MaybeAlign());
+ B.setSwitchIndexType(IndexType);
} else {
assert(PromiseAlloca == nullptr && "lowering doesn't support promises");
}
@@ -927,21 +848,26 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
FrameData.setFieldIndex(S.first, Id);
}
- StructType *FrameTy = [&] {
+ {
SmallString<32> Name(F.getName());
Name.append(".Frame");
- return B.finish(Name);
- }();
+ B.finish(Name);
+ }
- FrameData.updateLayoutIndex(B);
+ FrameData.updateLayoutInfo(B);
Shape.FrameAlign = B.getStructAlign();
Shape.FrameSize = B.getStructSize();
switch (Shape.ABI) {
case coro::ABI::Switch: {
- // In the switch ABI, remember the switch-index field.
+ // In the switch ABI, remember the function pointer and index field info.
+ // Resume and Destroy function pointers are in the frame header.
+ const DataLayout &DL = F.getDataLayout();
+ Shape.SwitchLowering.ResumeOffset = 0;
+ Shape.SwitchLowering.DestroyOffset = DL.getPointerSize();
+
auto IndexField = B.getLayoutField(*SwitchIndexFieldId);
- Shape.SwitchLowering.IndexField = IndexField.LayoutFieldIndex;
+ Shape.SwitchLowering.IndexType = B.getSwitchIndexType();
Shape.SwitchLowering.IndexAlign = IndexField.Alignment.value();
Shape.SwitchLowering.IndexOffset = IndexField.Offset;
@@ -976,8 +902,6 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
break;
}
}
-
- return FrameTy;
}
/// If MaybeArgument is a byval Argument, return its byval type. Also removes
@@ -997,64 +921,58 @@ static Type *extractByvalIfArgument(Value *MaybeArgument) {
static void createStoreIntoFrame(IRBuilder<> &Builder, Value *Def,
Type *ByValTy, const coro::Shape &Shape,
const FrameDataInfo &FrameData) {
- auto Index = FrameData.getFieldIndex(Def);
- auto *G = Builder.CreateConstInBoundsGEP2_32(
- Shape.FrameTy, Shape.FramePtr, 0, Index,
- Def->getName() + Twine(".spill.addr"));
+ LLVMContext &Ctx = Shape.CoroBegin->getContext();
+ uint64_t Offset = FrameData.getOffset(Def);
+
+ Value *G = Shape.FramePtr;
+ if (Offset != 0) {
+ auto *OffsetVal = ConstantInt::get(Type::getInt64Ty(Ctx), Offset);
+ G = Builder.CreateInBoundsPtrAdd(G, OffsetVal,
+ Def->getName() + Twine(".spill.addr"));
+ }
auto SpillAlignment = Align(FrameData.getAlign(Def));
- // For byval arguments, store the pointed-to value in the frame.
- if (ByValTy)
- Builder.CreateAlignedStore(Builder.CreateLoad(ByValTy, Def), G,
- SpillAlignment);
- else
+ // For byval arguments, copy the pointed-to value to the frame.
+ if (ByValTy) {
+ auto &DL = Builder.GetInsertBlock()->getDataLayout();
+ auto Size = DL.getTypeStoreSize(ByValTy);
+ // Def is a pointer to the byval argument
+ Builder.CreateMemCpy(G, SpillAlignment, Def, SpillAlignment, Size);
+ } else {
Builder.CreateAlignedStore(Def, G, SpillAlignment);
+ }
}
-/// Returns a GEP into the coroutine frame at the offset where Orig is located.
+/// Returns a pointer into the coroutine frame at the offset where Orig is
+/// located.
static Value *createGEPToFramePointer(const FrameDataInfo &FrameData,
IRBuilder<> &Builder, coro::Shape &Shape,
Value *Orig) {
LLVMContext &Ctx = Shape.CoroBegin->getContext();
- FieldIDType Index = FrameData.getFieldIndex(Orig);
- SmallVector<Value *, 3> Indices = {
- ConstantInt::get(Type::getInt32Ty(Ctx), 0),
- ConstantInt::get(Type::getInt32Ty(Ctx), Index),
- };
+ uint64_t Offset = FrameData.getOffset(Orig);
+ auto *OffsetVal = ConstantInt::get(Type::getInt64Ty(Ctx), Offset);
+ Value *Ptr = Builder.CreateInBoundsPtrAdd(Shape.FramePtr, OffsetVal);
- // If Orig is an array alloca, preserve the original type by adding an extra
- // zero offset.
- if (auto *AI = dyn_cast<AllocaInst>(Orig)) {
- if (ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
- auto Count = CI->getValue().getZExtValue();
- if (Count > 1)
- Indices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
- } else {
- report_fatal_error("Coroutines cannot handle non static allocas yet");
- }
- }
-
- auto *GEP = Builder.CreateInBoundsGEP(Shape.FrameTy, Shape.FramePtr, Indices);
if (auto *AI = dyn_cast<AllocaInst>(Orig)) {
if (FrameData.getDynamicAlign(Orig) != 0) {
assert(FrameData.getDynamicAlign(Orig) == AI->getAlign().value());
auto *M = AI->getModule();
auto *IntPtrTy = M->getDataLayout().getIntPtrType(AI->getType());
- auto *PtrValue = Builder.CreatePtrToInt(GEP, IntPtrTy);
+ auto *PtrValue = Builder.CreatePtrToInt(Ptr, IntPtrTy);
auto *AlignMask = ConstantInt::get(IntPtrTy, AI->getAlign().value() - 1);
PtrValue = Builder.CreateAdd(PtrValue, AlignMask);
PtrValue = Builder.CreateAnd(PtrValue, Builder.CreateNot(AlignMask));
return Builder.CreateIntToPtr(PtrValue, AI->getType());
}
- // If the type of GEP is not equal to the type of AllocaInst, it implies
+ // If the type of Ptr is not equal to the type of AllocaInst, it implies
// that the AllocaInst may be reused in the Frame slot of other AllocaInst.
// Note: If the strategy dealing with alignment changes, this cast must be
// refined
- if (GEP->getType() != Orig->getType())
- GEP = Builder.CreateAddrSpaceCast(GEP, Orig->getType(),
+ if (Ptr->getType() != Orig->getType())
+ Ptr = Builder.CreateAddrSpaceCast(Ptr, Orig->getType(),
Orig->getName() + Twine(".cast"));
}
- return GEP;
+ return Ptr;
}
/// Find dbg.declare or dbg.declare_value records referencing `Def`. If none are
@@ -1113,7 +1031,6 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
LLVMContext &C = Shape.CoroBegin->getContext();
Function *F = Shape.CoroBegin->getFunction();
IRBuilder<> Builder(C);
- StructType *FrameTy = Shape.FrameTy;
DominatorTree DT(*F);
SmallDenseMap<Argument *, AllocaInst *, 4> ArgToAllocaMap;
@@ -1155,9 +1072,9 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
CurrentReload = GEP;
} else {
auto SpillAlignment = Align(FrameData.getAlign(Def));
- auto *LI = Builder.CreateAlignedLoad(
- FrameTy->getElementType(FrameData.getFieldIndex(E.first)), GEP,
- SpillAlignment, E.first->getName() + Twine(".reload"));
+ auto *LI =
+ Builder.CreateAlignedLoad(E.first->getType(), GEP, SpillAlignment,
+ E.first->getName() + Twine(".reload"));
if (TBAATag)
LI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
CurrentReload = LI;
@@ -1303,13 +1220,14 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
AllocaInst *Alloca = A.Alloca;
if (A.MayWriteBeforeCoroBegin) {
// isEscaped really means potentially modified before CoroBegin.
- if (Alloca->isArrayAllocation())
- report_fatal_error(
- "Coroutines cannot handle copying of array allocas yet");
-
+ // TODO: use Builder.CreateAllocationSize here once that PR is merged
+ auto Size = Alloca->getAllocationSize(Alloca->getDataLayout());
+ assert(Size &&
+ "Coroutines cannot handle copying of dynamic allocas yet.\n");
+ assert(!Size->isScalable() && "Scalable vectors are not yet supported");
auto *G = createGEPToFramePointer(FrameData, Builder, Shape, Alloca);
- auto *Value = Builder.CreateLoad(Alloca->getAllocatedType(), Alloca);
- Builder.CreateStore(Value, G);
+ Builder.CreateMemCpy(G, FrameData.getAlign(Alloca), Alloca,
+ Alloca->getAlign(), Size->getFixedValue());
}
// For each alias to Alloca created before CoroBegin but used after
// CoroBegin, we recreate them after CoroBegin by applying the offset
@@ -1320,7 +1238,7 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
auto &Value = *Alias.second;
auto ITy = IntegerType::get(C, Value.getBitWidth());
auto *AliasPtr =
- Builder.CreatePtrAdd(FramePtr, ConstantInt::get(ITy, Value));
+ Builder.CreateInBoundsPtrAdd(FramePtr, ConstantInt::get(ITy, Value));
Alias.first->replaceUsesWithIf(
AliasPtr, [&](Use &U) { return DT.dominates(Shape.CoroBegin, U); });
}
@@ -1361,9 +1279,14 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
});
if (HasAccessingPromiseBeforeCB) {
Builder.SetInsertPoint(&*Shape.getInsertPtAfterFramePtr());
+ // TODO: use Builder.CreateAllocationSize here once that PR is merged
+ auto Size = PA->getAllocationSize(PA->getDataLayout());
+ assert(Size &&
+ "Coroutines cannot handle copying of dynamic allocas yet.\n");
+ assert(!Size->isScalable() && "Scalable vectors are not yet supported");
auto *G = createGEPToFramePointer(FrameData, Builder, Shape, PA);
- auto *Value = Builder.CreateLoad(PA->getAllocatedType(), PA);
- Builder.CreateStore(Value, G);
+ Builder.CreateMemCpy(G, FrameData.getAlign(PA), PA, PA->getAlign(),
+ Size->getFixedValue());
}
}
}
@@ -2127,9 +2050,9 @@ void coro::BaseABI::buildCoroutineFrame(bool OptimizeFrame) {
Shape.ABI == coro::ABI::Async)
sinkSpillUsesAfterCoroBegin(DT, Shape.CoroBegin, Spills, Allocas);
- // Build frame
+ // Build frame layout
FrameDataInfo FrameData(Spills, Allocas);
- Shape.FrameTy = buildFrameType(F, Shape, FrameData, OptimizeFrame);
+ buildFrameLayout(F, Shape, FrameData, OptimizeFrame);
Shape.FramePtr = Shape.CoroBegin;
// For now, this works for C++ programs only.
buildFrameDebugInfo(F, Shape, FrameData);
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index f83b6a601572d..2d6b893af3051 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -315,11 +315,14 @@ static void markCoroutineAsDone(IRBuilder<> &Builder, const coro::Shape &Shape,
assert(
Shape.ABI == coro::ABI::Switch &&
"markCoroutineAsDone is only supported for Switch-Resumed ABI for now.");
- auto *GepIndex = Builder.CreateStructGEP(
- Shape.FrameTy, FramePtr, coro::Shape::SwitchFieldIndex::Resume,
- "ResumeFn.addr");
- auto *NullPtr = ConstantPointerNull::get(cast<PointerType>(
- Shape.FrameTy->getTypeAtIndex(coro::Shape::SwitchFieldIndex::Resume)));
+ // Resume function pointer
+ Value *GepIndex = FramePtr;
+ if (Shape.SwitchLowering.ResumeOffset != 0) {
+ GepIndex = Builder.CreateInBoundsPtrAdd(
+ FramePtr, ConstantInt::get(Type::getInt64Ty(FramePtr->getContext()),
+ Shape.SwitchLowering.ResumeOffset));
+ }
+ auto *NullPtr = ConstantPointerNull::get(Shape.getSwitchResumePointerType());
Builder.CreateStore(NullPtr, GepIndex);
// If the coroutine don't have unwind coro end, we could omit the store to
@@ -336,9 +339,10 @@ static void markCoroutineAsDone(IRBuilder<> &Builder, const coro::Shape &Shape,
"The final suspend should only live in the last position of "
"CoroSuspends.");
ConstantInt *IndexVal = Shape.getIndex(Shape.CoroSuspends.size() - 1);
- auto *FinalIndex = Builder.CreateStructGEP(
- Shape.FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr");
-
+ auto *Offset = ConstantInt::get(Type::getInt64Ty(FramePtr->getContext()),
+ Shape.SwitchLowering.IndexOffset);
+ Value *FinalIndex =
+ Builder.CreateInBoundsPtrAdd(FramePtr, Offset, "index.addr");
Builder.CreateStore(IndexVal, FinalIndex);
}
}
@@ -420,9 +424,14 @@ void coro::BaseCloner::handleFinalSuspend() {
// to generate code for other cases.
Builder.CreateBr(ResumeBB);
} else {
- auto *GepIndex = Builder.CreateStructGEP(
- Shape.FrameTy, NewFramePtr, coro::Shape::SwitchFieldIndex::Resume,
- "ResumeFn.addr");
+ // Resume function pointer
+ Value *GepIndex = NewFramePtr;
+ if (Shape.SwitchLowering.ResumeOffset != 0) {
+ GepIndex = Builder.CreateInBoundsPtrAdd(
+ NewFramePtr,
+ ConstantInt::get(Type::getInt64Ty(NewFramePtr->getContext()),
+ Shape.SwitchLowering.ResumeOffset));
+ }
auto *Load =
Builder.CreateLoad(Shape.getSwitchResumePointerType(), GepIndex);
auto *Cond = Builder.CreateIsNull(Load);
@@ -766,9 +775,11 @@ Value *coro::BaseCloner::deriveNewFramePointer() {
CallerContext->setDebugLoc(DbgLoc);
// The frame is located after the async_context header.
auto &Context = Builder.getContext();
- auto *FramePtrAddr = Builder.CreateConstInBoundsGEP1_32(
- Type::getInt8Ty(Context), CallerContext,
- Shape.AsyncLowering.FrameOffset, "async.ctx.frameptr");
+ auto *FramePtrAddr = Builder.CreateInBoundsPtrAdd(
+ CallerContext,
+ ConstantInt::get(Type::getInt64Ty(Context),
+ Shape.AsyncLowering.FrameOffset),
+ "async.ctx.frameptr");
// Inline the projection function.
InlineFunctionInfo InlineInfo;
auto InlineRes = InlineFunction(*CallerContext, InlineInfo);
@@ -780,7 +791,7 @@ Value *coro::BaseCloner::deriveNewFramePointer() {
case coro::ABI::Retcon:
case coro::ABI::RetconOnce: {
Argument *NewStorage = &*NewF->arg_begin();
- auto FramePtrTy = PointerType::getUnqual(Shape.FrameTy->getContext());
+ auto FramePtrTy = PointerType::getUnqual(Shape.FramePtr->getContext());
// If the storage is inline, just bitcast to the storage to the frame type.
if (Shape.RetconLowering.IsFrameInlineInStorage)
@@ -1119,11 +1130,7 @@ static void updateAsyncFuncPointerContextSize(coro::Shape &Shape) {
}
static TypeSize getFrameSizeForShape(coro::Shape &Shape) {
- // In the same function all coro.sizes should have the same result type.
- auto *SizeIntrin = Shape.CoroSizes.back();
- Module *M = SizeIntrin->getModule();
- const DataLayout &DL = M->getDataLayout();
- return DL.getTypeAllocSize(Shape.FrameTy);
+ return TypeSize::getFixed(Shape.FrameSize);
}
static void replaceFrameSizeAndAlignment(coro::Shape &Shape) {
@@ -1173,7 +1180,10 @@ static void handleNoSuspendCoroutine(coro::Shape &Shape) {
coro::replaceCoroFree(SwitchId, /*Elide=*/AllocInst != nullptr);
if (AllocInst) {
IRBuilder<> Builder(AllocInst);
- auto *Frame = Builder.CreateAlloca(Shape.FrameTy);
+ // Create an alloca for a byte array of the frame size
+ auto *FrameTy = ArrayType::get(Type::getInt8Ty(Builder.getContext()),
+ Shape.FrameSize);
+ auto *Frame = Builder.CreateAlloca(FrameTy);
Frame->setAlignment(Shape.FrameAlign);
AllocInst->replaceAllUsesWith(Builder.getFalse());
AllocInst->eraseFromParent();
@@ -1420,7 +1430,7 @@ struct SwitchCoroutineSplitter {
SmallVector<Type *> NewParams;
NewParams.reserve(OldParams.size() + 1);
NewParams.append(OldParams.begin(), OldParams.end());
- NewParams.push_back(PointerType::getUnqual(Shape.FrameTy->getContext()));
+ NewParams.push_back(PointerType::getUnqual(Shape.FramePtr->getContext()));
auto *NewFnTy = FunctionType::get(OrigFnTy->getReturnType(), NewParams,
OrigFnTy->isVarArg());
@@ -1502,9 +1512,10 @@ struct SwitchCoroutineSplitter {
IRBuilder<> Builder(NewEntry);
auto *FramePtr = Shape.FramePtr;
- auto *FrameTy = Shape.FrameTy;
- auto *GepIndex = Builder.CreateStructGEP(
- FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr");
+ auto *Offset =
+ ConstantInt::get(Type::getInt64Ty(C), Shape.SwitchLowering.IndexOffset);
+ Value *GepIndex =
+ Builder.CreateInBoundsPtrAdd(FramePtr, Offset, "index.addr");
auto *Index = Builder.CreateLoad(Shape.getIndexType(), GepIndex, "index");
auto *Switch =
Builder.CreateSwitch(Index, UnreachBB, Shape.CoroSuspends.size());
@@ -1526,8 +1537,10 @@ struct SwitchCoroutineSplitter {
// point.
markCoroutineAsDone(Builder, Shape, FramePtr);
} else {
- auto *GepIndex = Builder.CreateStructGEP(
- FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr");
+ auto *Offset = ConstantInt::get(Type::getInt64Ty(C),
+ Shape.SwitchLowering.IndexOffset);
+ Value *GepIndex =
+ Builder.CreateInBoundsPtrAdd(FramePtr, Offset, "index.addr");
Builder.CreateStore(IndexVal, GepIndex);
}
@@ -1609,10 +1622,17 @@ struct SwitchCoroutineSplitter {
static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn,
Function *DestroyFn, Function *CleanupFn) {
IRBuilder<> Builder(&*Shape.getInsertPtAfterFramePtr());
-
- auto *ResumeAddr = Builder.CreateStructGEP(
- Shape.FrameTy, Shape.FramePtr, coro::Shape::SwitchFieldIndex::Resume,
- "resume.addr");
+ LLVMContext &C = ResumeFn->getContext();
+
+ // Resume function pointer
+ Value *ResumeAddr = Shape.FramePtr;
+ if (Shape.SwitchLowering.ResumeOffset != 0) {
+ ResumeAddr = Builder.CreateInBoundsPtrAdd(
+ Shape.FramePtr,
+ ConstantInt::get(Type::getInt64Ty(C),
+ Shape.SwitchLowering.ResumeOffset),
+ "resume.addr");
+ }
Builder.CreateStore(ResumeFn, ResumeAddr);
Value *DestroyOrCleanupFn = DestroyFn;
@@ -1624,8 +1644,11 @@ struct SwitchCoroutineSplitter {
DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn);
}
- auto *DestroyAddr = Builder.CreateStructGEP(
- Shape.FrameTy, Shape.FramePtr, coro::Shape::SwitchFieldIndex::Destroy,
+ // Destroy function pointer
+ Value *DestroyAddr = Builder.CreateInBoundsPtrAdd(
+ Shape.FramePtr,
+ ConstantInt::get(Type::getInt64Ty(C),
+ Shape.SwitchLowering.DestroyOffset),
"destroy.addr");
Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr);
}
@@ -1736,8 +1759,10 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
auto *FramePtr = Id->getStorage();
FramePtr = Builder.CreateBitOrPointerCast(FramePtr, Int8PtrTy);
- FramePtr = Builder.CreateConstInBoundsGEP1_32(
- Type::getInt8Ty(Context), FramePtr, Shape.AsyncLowering.FrameOffset,
+ FramePtr = Builder.CreateInBoundsPtrAdd(
+ FramePtr,
+ ConstantInt::get(Type::getInt64Ty(Context),
+ Shape.AsyncLowering.FrameOffset),
"async.ctx.frameptr");
// Map all uses of llvm.coro.begin to the allocated frame pointer.
@@ -1834,14 +1859,12 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
} else {
IRBuilder<> Builder(Id);
- // Determine the size of the frame.
- const DataLayout &DL = F.getDataLayout();
- auto Size = DL.getTypeAllocSize(Shape.FrameTy);
+ auto FrameSize = Builder.getInt64(Shape.FrameSize);
// Allocate. We don't need to update the call graph node because we're
// going to recompute it from scratch after splitting.
// FIXME: pass the required alignment
- RawFramePtr = Shape.emitAlloc(Builder, Builder.getInt64(Size), nullptr);
+ RawFramePtr = Shape.emitAlloc(Builder, FrameSize, nullptr);
RawFramePtr =
Builder.CreateBitCast(RawFramePtr, Shape.CoroBegin->getType());
diff --git a/llvm/test/Transforms/Coroutines/ArgAddr.ll b/llvm/test/Transforms/Coroutines/ArgAddr.ll
index b8a478c86a767..c6fca4996d86c 100644
--- a/llvm/test/Transforms/Coroutines/ArgAddr.ll
+++ b/llvm/test/Transforms/Coroutines/ArgAddr.ll
@@ -3,6 +3,8 @@
; coro.begin.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
define nonnull ptr @f(i32 %n) presplitcoroutine {
; CHECK-LABEL: define nonnull ptr @f(
; CHECK-SAME: i32 [[N:%.*]]) {
@@ -13,17 +15,16 @@ define nonnull ptr @f(i32 %n) presplitcoroutine {
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @malloc(i32 24)
; CHECK-NEXT: [[TMP0:%.*]] = tail call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[CALL]])
; CHECK-NEXT: store ptr @f.resume, ptr [[TMP0]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP0]], i32 0, i32 2
-; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[N_ADDR]], align 4
-; CHECK-NEXT: store i32 [[TMP2]], ptr [[TMP1]], align 4
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 16
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[TMP1]], ptr align 4 [[N_ADDR]], i64 4, i1 false)
; CHECK-NEXT: call void @ctor(ptr [[TMP1]])
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP1]], align 4
; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[TMP3]], -1
; CHECK-NEXT: store i32 [[DEC]], ptr [[TMP1]], align 4
; CHECK-NEXT: call void @print(i32 [[TMP3]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[TMP0]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 20
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[TMP0]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-align16.ll b/llvm/test/Transforms/Coroutines/coro-align16.ll
index 6ff6576a4bc8e..e74f23e8e531c 100644
--- a/llvm/test/Transforms/Coroutines/coro-align16.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align16.ll
@@ -2,18 +2,19 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, i64, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @f.resumers)
-; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 16, i32 40)
+; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 16, i32 48)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-align32.ll b/llvm/test/Transforms/Coroutines/coro-align32.ll
index f95bf690e4f75..6f61a32fde95a 100644
--- a/llvm/test/Transforms/Coroutines/coro-align32.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align32.ll
@@ -2,18 +2,19 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, i1, i1, [6 x i8], i32, [12 x i8], i32 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @f.resumers)
-; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 32, i32 56)
+; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 32, i32 64)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-align64-02.ll b/llvm/test/Transforms/Coroutines/coro-align64-02.ll
index 1be0c0bb7e292..471e4fc751378 100644
--- a/llvm/test/Transforms/Coroutines/coro-align64-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align64-02.ll
@@ -2,18 +2,19 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i1, [15 x i8], i64, [24 x i8], i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @f.resumers)
-; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 64, i32 72)
+; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 64, i32 128)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-align64.ll b/llvm/test/Transforms/Coroutines/coro-align64.ll
index a264d614a4a99..801a7a1d89a9a 100644
--- a/llvm/test/Transforms/Coroutines/coro-align64.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align64.ll
@@ -2,18 +2,19 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, i1, [39 x i8], i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @f.resumers)
-; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 64, i32 72)
+; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 64, i32 128)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-align8-02.ll b/llvm/test/Transforms/Coroutines/coro-align8-02.ll
index b4c199d5c5173..5a09b211ccfe4 100644
--- a/llvm/test/Transforms/Coroutines/coro-align8-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align8-02.ll
@@ -2,7 +2,8 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
@@ -11,9 +12,9 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 8, i32 24)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-align8.ll b/llvm/test/Transforms/Coroutines/coro-align8.ll
index 6c2e7afe58ac6..d98fd10a44655 100644
--- a/llvm/test/Transforms/Coroutines/coro-align8.ll
+++ b/llvm/test/Transforms/Coroutines/coro-align8.ll
@@ -2,7 +2,8 @@
; Tests that the coro.align intrinsic could be lowered to correct alignment
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
@@ -11,9 +12,9 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @aligned_alloc(i32 8, i32 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
index ae6f8c78cad6d..2db096f13136d 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O0.ll
@@ -54,11 +54,11 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @myAlloc(i64 [[THIS_ARG]], i32 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f_copy.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_COPY_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f_copy.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[THIS_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_COPY_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[THIS_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i64 [[THIS_ARG]], ptr [[THIS_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_COPY_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -66,7 +66,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f_copy.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(32) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[THIS_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_COPY_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[THIS_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[THIS_RELOAD:%.*]] = load i64, ptr [[THIS_RELOAD_ADDR]], align 4
; CHECK-NEXT: call void @print2(i64 [[THIS_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
diff --git a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
index 6ba13750ce943..e079d8114cc23 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloc-with-param-O2.ll
@@ -49,11 +49,11 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @myAlloc(i64 [[THIS]], i32 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f_direct.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_DIRECT_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f_direct.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[THIS_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_DIRECT_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[THIS_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i64 [[THIS]], ptr [[THIS_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_DIRECT_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -61,7 +61,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f_direct.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(32) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[THIS_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_DIRECT_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[THIS_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[THIS_RELOAD:%.*]] = load i64, ptr [[THIS_RELOAD_ADDR]], align 4
; CHECK-NEXT: call void @print2(i64 [[THIS_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-01.ll b/llvm/test/Transforms/Coroutines/coro-alloca-01.ll
index 51d72bfaa2d29..64530553c254a 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-01.ll
@@ -3,7 +3,8 @@
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, i64, ptr, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f(i1 %n) presplitcoroutine {
; CHECK-LABEL: define ptr @f(
@@ -13,18 +14,18 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 48)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: br i1 [[N]], label %[[MERGE:.*]], label %[[MERGE_FROM_FLAG_FALSE:.*]]
; CHECK: [[MERGE_FROM_FLAG_FALSE]]:
; CHECK-NEXT: br label %[[MERGE]]
; CHECK: [[MERGE]]:
; CHECK-NEXT: [[ALIAS_PHI:%.*]] = phi ptr [ [[Y_RELOAD_ADDR]], %[[MERGE_FROM_FLAG_FALSE]] ], [ [[X_RELOAD_ADDR]], %[[ENTRY]] ]
-; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store ptr [[ALIAS_PHI]], ptr [[ALIAS_PHI_SPILL_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 40
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-02.ll b/llvm/test/Transforms/Coroutines/coro-alloca-02.ll
index e760bd59a2e4c..5dfa4892c03d3 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-02.ll
@@ -3,7 +3,8 @@
; the alloac will be put on the frame.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, ptr, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
@@ -12,12 +13,12 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 40)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store ptr [[X_RELOAD_ADDR]], ptr [[Y_RELOAD_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-03.ll b/llvm/test/Transforms/Coroutines/coro-alloca-03.ll
index 4609cf8403dd4..4c5e4393dae90 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-03.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-03.ll
@@ -2,7 +2,8 @@
; Tests that allocas escaped through function calls will live on the frame.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
@@ -12,12 +13,12 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: call void @capture_call(ptr [[X_RELOAD_ADDR]])
; CHECK-NEXT: call void @nocapture_call(ptr [[Y]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-04.ll b/llvm/test/Transforms/Coroutines/coro-alloca-04.ll
index 2839e9c7e5581..f31c0fc32defc 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-04.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-04.ll
@@ -3,7 +3,8 @@
; if their aliases are used across suspension points through PHINode.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i64, ptr, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f(i1 %n) presplitcoroutine {
; CHECK-LABEL: define ptr @f(
@@ -13,12 +14,12 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 40)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store ptr [[TMP0]], ptr [[ALIAS_PHI_SPILL_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-06.ll b/llvm/test/Transforms/Coroutines/coro-alloca-06.ll
index bf338b1aedbe2..e9c54f8c49171 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-06.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-06.ll
@@ -3,9 +3,10 @@
; though their pointers are stored.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
%handle = type { ptr }
-; CHECK: %f.Frame = type { ptr, ptr, i1 }
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
@@ -16,14 +17,14 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 24)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[TMP2:%.*]] = call ptr @await_suspend()
; CHECK-NEXT: store ptr [[TMP2]], ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TMP1]])
; CHECK-NEXT: store ptr [[TMP0]], ptr [[TMP1]], align 8
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TMP1]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-07.ll b/llvm/test/Transforms/Coroutines/coro-alloca-07.ll
index 5a37387ed4492..76aca567f785b 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-07.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-07.ll
@@ -67,19 +67,19 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 48)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: br i1 [[N]], label %[[MERGE:.*]], label %[[MERGE_FROM_FLAG_FALSE:.*]]
; CHECK: [[MERGE_FROM_FLAG_FALSE]]:
; CHECK-NEXT: br label %[[MERGE]]
; CHECK: [[MERGE]]:
; CHECK-NEXT: [[ALIAS_PHI:%.*]] = phi ptr [ [[Y_RELOAD_ADDR]], %[[MERGE_FROM_FLAG_FALSE]] ], [ [[X_RELOAD_ADDR]], %[[ENTRY]] ]
-; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store ptr [[ALIAS_PHI]], ptr [[ALIAS_PHI_SPILL_ADDR]], align 8
; CHECK-NEXT: store i8 1, ptr [[ALIAS_PHI]], align 1
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 40
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -87,7 +87,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(48) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[ALIAS_PHI_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[ALIAS_PHI_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: [[ALIAS_PHI_RELOAD:%.*]] = load ptr, ptr [[ALIAS_PHI_RELOAD_ADDR]], align 8
; CHECK-NEXT: call void @print(ptr [[ALIAS_PHI_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-08.ll b/llvm/test/Transforms/Coroutines/coro-alloca-08.ll
index d267e49acc056..2c863b4838237 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-08.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-08.ll
@@ -2,12 +2,12 @@
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
; Verify that for both foo and bar, testval isn't put on the frame.
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
%"struct.std::coroutine_handle" = type { ptr }
%"struct.std::coroutine_handle.0" = type { %"struct.std::coroutine_handle" }
%"struct.lean_future<int>::Awaiter" = type { i32, %"struct.std::coroutine_handle.0" }
-; CHECK: %foo.Frame = type { ptr, ptr, i1 }
-; CHECK: %bar.Frame = type { ptr, ptr, i1 }
declare ptr @malloc(i64)
@@ -24,12 +24,12 @@ define void @foo() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @foo.resume, ptr [[VFRAME]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[FOO_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @foo.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[TESTVAL]])
; CHECK-NEXT: call void @consume.i8.array(ptr [[TESTVAL]])
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[TESTVAL]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
@@ -67,9 +67,9 @@ define void @bar() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @bar.resume, ptr [[VFRAME]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[BAR_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @bar.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[BAR_FRAME]], ptr [[VFRAME]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: br i1 false, label %[[AWAIT_READY:.*]], label %[[AFTERCOROEND:.*]]
; CHECK: [[AWAIT_READY]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-09.ll b/llvm/test/Transforms/Coroutines/coro-alloca-09.ll
index 4736790dfe324..42b75c18c1a65 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-09.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-09.ll
@@ -11,19 +11,19 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[MEM:%.*]] = call ptr @malloc(i32 56)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[MEM]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[ALIAS_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[ALIAS_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i64 0, ptr [[X_RELOAD_ADDR]], align 4
; CHECK-NEXT: store i64 0, ptr [[ALIAS_SPILL_ADDR]], align 4
; CHECK-NEXT: [[X_ALIAS:%.*]] = insertvalue [1 x ptr] poison, ptr [[X_RELOAD_ADDR]], 0
-; CHECK-NEXT: [[X_ALIAS_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[X_ALIAS_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store [1 x ptr] [[X_ALIAS]], ptr [[X_ALIAS_SPILL_ADDR]], align 8
; CHECK-NEXT: [[Y_ALIAS:%.*]] = insertelement <1 x ptr> poison, ptr [[ALIAS_SPILL_ADDR]], i32 0
-; CHECK-NEXT: [[Y_ALIAS_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[Y_ALIAS_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 40
; CHECK-NEXT: store <1 x ptr> [[Y_ALIAS]], ptr [[Y_ALIAS_SPILL_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 6
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 48
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll b/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll
index baec3f1a0c869..5d100df9424c0 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-loop-carried-address.ll
@@ -11,10 +11,10 @@ define void @foo() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 40)
; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @foo.resume, ptr [[VFRAME]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[FOO_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @foo.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[STACKVAR0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 2
-; CHECK-NEXT: [[STACKVAR1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 3
+; CHECK-NEXT: [[STACKVAR0_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
+; CHECK-NEXT: [[STACKVAR1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 24
; CHECK-NEXT: [[STACKVAR0_INT:%.*]] = ptrtoint ptr [[STACKVAR0_RELOAD_ADDR]] to i64
; CHECK-NEXT: store i64 [[STACKVAR0_INT]], ptr @escape_hatch0, align 4
; CHECK-NEXT: [[STACKVAR1_INT:%.*]] = ptrtoint ptr [[STACKVAR1_RELOAD_ADDR]] to i64
@@ -23,7 +23,7 @@ define void @foo() presplitcoroutine {
; CHECK: loop:
; CHECK-NEXT: store i64 1234, ptr [[STACKVAR0_RELOAD_ADDR]], align 4
; CHECK-NEXT: call void @bar()
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[FOO_FRAME]], ptr [[VFRAME]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 32
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[AFTERCOROEND:%.*]]
; CHECK: AfterCoroEnd:
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-with-addrspace.ll b/llvm/test/Transforms/Coroutines/coro-alloca-with-addrspace.ll
index 8c23147ee6072..8d568016b7a29 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-with-addrspace.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-with-addrspace.ll
@@ -11,20 +11,20 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 48)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = addrspacecast ptr [[TMP0]] to ptr addrspace(5)
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = addrspacecast ptr [[TMP1]] to ptr addrspace(5)
; CHECK-NEXT: br i1 [[N]], label %[[FLAG_TRUE:.*]], label %[[FLAG_FALSE:.*]]
; CHECK: [[FLAG_FALSE]]:
; CHECK-NEXT: br label %[[FLAG_TRUE]]
; CHECK: [[FLAG_TRUE]]:
; CHECK-NEXT: [[ALIAS_PHI:%.*]] = phi ptr addrspace(5) [ [[Y_RELOAD_ADDR]], %[[FLAG_FALSE]] ], [ [[X_RELOAD_ADDR]], %[[ENTRY]] ]
-; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[ALIAS_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store ptr addrspace(5) [[ALIAS_PHI]], ptr [[ALIAS_PHI_SPILL_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 40
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll b/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
index 802d1e432bf5c..58104ebc5aebf 100644
--- a/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
+++ b/llvm/test/Transforms/Coroutines/coro-async-dyn-align.ll
@@ -9,7 +9,6 @@ target datalayout = "p:64:64:64"
%async.ctxt = type { ptr, ptr }
-; CHECK: %my_async_function.Frame = type { i64, [48 x i8], i64, i64, [16 x i8], ptr, i64, ptr }
@my_other_async_function_fp = external global <{ i32, i32 }>
declare void @my_other_async_function(ptr %async.ctxt)
@@ -64,27 +63,27 @@ define swiftcc void @my_async_function(ptr swiftasync %async.ctxt) presplitcorou
; CHECK-LABEL: define swiftcc void @my_async_function(
; CHECK-SAME: ptr swiftasync [[ASYNC_CTXT:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[ASYNC_CTX_FRAMEPTR:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTXT]], i32 32
-; CHECK-NEXT: [[STACK:%.*]] = getelementptr inbounds [[MY_ASYNC_FUNCTION_FRAME:%.*]], ptr [[ASYNC_CTX_FRAMEPTR]], i32 0, i32 2
-; CHECK-NEXT: [[STACK2:%.*]] = getelementptr inbounds [[MY_ASYNC_FUNCTION_FRAME]], ptr [[ASYNC_CTX_FRAMEPTR]], i32 0, i32 6
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[MY_ASYNC_FUNCTION_FRAME]], ptr [[ASYNC_CTX_FRAMEPTR]], i32 0, i32 3
+; CHECK-NEXT: [[ASYNC_CTX_FRAMEPTR:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTXT]], i64 32
+; CHECK-NEXT: [[STACK:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTX_FRAMEPTR]], i64 56
+; CHECK-NEXT: [[STACK2:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTX_FRAMEPTR]], i64 96
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTX_FRAMEPTR]], i64 64
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], -32
; CHECK-NEXT: [[STACK3:%.*]] = inttoptr i64 [[TMP3]] to ptr
-; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[MY_ASYNC_FUNCTION_FRAME]], ptr [[ASYNC_CTX_FRAMEPTR]], i32 0, i32 0
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTX_FRAMEPTR]], i64 0
; CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP4]] to i64
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], 63
; CHECK-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], -64
; CHECK-NEXT: [[STACK4:%.*]] = inttoptr i64 [[TMP7]] to ptr
-; CHECK-NEXT: [[ASYNC_CTXT_SPILL_ADDR:%.*]] = getelementptr inbounds [[MY_ASYNC_FUNCTION_FRAME]], ptr [[ASYNC_CTX_FRAMEPTR]], i32 0, i32 5
+; CHECK-NEXT: [[ASYNC_CTXT_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTX_FRAMEPTR]], i64 88
; CHECK-NEXT: store ptr [[ASYNC_CTXT]], ptr [[ASYNC_CTXT_SPILL_ADDR]], align 8
; CHECK-NEXT: store i64 0, ptr [[STACK]], align 4
; CHECK-NEXT: store i64 1, ptr [[STACK2]], align 4
; CHECK-NEXT: store i64 2, ptr [[STACK3]], align 4
; CHECK-NEXT: store i64 3, ptr [[STACK4]], align 4
; CHECK-NEXT: [[CALLEE_CONTEXT:%.*]] = call ptr @llvm.coro.async.context.alloc(ptr null, ptr null)
-; CHECK-NEXT: [[CALLEE_CONTEXT_SPILL_ADDR:%.*]] = getelementptr inbounds [[MY_ASYNC_FUNCTION_FRAME]], ptr [[ASYNC_CTX_FRAMEPTR]], i32 0, i32 7
+; CHECK-NEXT: [[CALLEE_CONTEXT_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[ASYNC_CTX_FRAMEPTR]], i64 104
; CHECK-NEXT: store ptr [[CALLEE_CONTEXT]], ptr [[CALLEE_CONTEXT_SPILL_ADDR]], align 8
; CHECK-NEXT: [[CALLEE_CONTEXT_RETURN_TO_CALLER_ADDR:%.*]] = getelementptr inbounds [[ASYNC_CTXT]], ptr [[CALLEE_CONTEXT]], i32 0, i32 1
; CHECK-NEXT: store ptr @my_async_functionTQ0_, ptr [[CALLEE_CONTEXT_RETURN_TO_CALLER_ADDR]], align 8
diff --git a/llvm/test/Transforms/Coroutines/coro-await-suspend-lower-invoke.ll b/llvm/test/Transforms/Coroutines/coro-await-suspend-lower-invoke.ll
index 0639c710cd420..72bb8fcf5b610 100644
--- a/llvm/test/Transforms/Coroutines/coro-await-suspend-lower-invoke.ll
+++ b/llvm/test/Transforms/Coroutines/coro-await-suspend-lower-invoke.ll
@@ -109,12 +109,11 @@ declare void @free(ptr)
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr @f, ptr @f.resumers)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 24)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
-; CHECK-NEXT: [[RESUME_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
-; CHECK-NEXT: store ptr @f.resume, ptr [[RESUME_ADDR]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 0
-; CHECK-NEXT: [[INDEX_ADDR12:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
+; CHECK-NEXT: [[INDEX_ADDR12:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 0, ptr [[INDEX_ADDR12]], align 1
; CHECK-NEXT: ret void
;
@@ -122,8 +121,8 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) personality i32 0 {
; CHECK-NEXT: [[ENTRY_RESUME:.*]]:
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
-; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
+; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[INDEX:%.*]] = load i2, ptr [[INDEX_ADDR]], align 1
; CHECK-NEXT: switch i2 [[INDEX]], label %[[UNREACHABLE:.*]] [
; CHECK-NEXT: i2 0, label %[[COROSAVE1:.*]]
@@ -132,7 +131,7 @@ declare void @free(ptr)
; CHECK-NEXT: i2 -1, label %[[CLEANUP:.*]]
; CHECK-NEXT: ]
; CHECK: [[COROSAVE1]]:
-; CHECK-NEXT: [[INDEX_ADDR13:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR13:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 1, ptr [[INDEX_ADDR13]], align 1
; CHECK-NEXT: invoke void @await_suspend_wrapper_void(ptr [[AWAITER_RELOAD_ADDR]], ptr [[HDL]])
; CHECK-NEXT: to label %[[AFTERCOROSUSPEND3]] unwind label %[[PAD:.*]]
@@ -141,7 +140,7 @@ declare void @free(ptr)
; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[TMP0]], 0
; CHECK-NEXT: br i1 [[COND]], label %[[COROSAVE4:.*]], label %[[COROEND:.*]]
; CHECK: [[COROSAVE4]]:
-; CHECK-NEXT: [[INDEX_ADDR14:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR14:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 -2, ptr [[INDEX_ADDR14]], align 1
; CHECK-NEXT: [[TMP1:%.*]] = invoke i1 @await_suspend_wrapper_bool(ptr [[AWAITER_RELOAD_ADDR]], ptr [[HDL]])
; CHECK-NEXT: to label %[[STEP1_CONTINUE:.*]] unwind label %[[PAD]]
@@ -152,7 +151,7 @@ declare void @free(ptr)
; CHECK-NEXT: [[COND1:%.*]] = icmp eq i8 [[TMP2]], 0
; CHECK-NEXT: br i1 [[COND1]], label %[[COROSAVE8]], label %[[COROEND]]
; CHECK: [[COROSAVE8]]:
-; CHECK-NEXT: [[INDEX_ADDR15:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR15:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 -1, ptr [[INDEX_ADDR15]], align 1
; CHECK-NEXT: [[TMP3:%.*]] = invoke ptr @await_suspend_wrapper_handle(ptr [[AWAITER_RELOAD_ADDR]], ptr [[HDL]])
; CHECK-NEXT: to label %[[STEP2_CONTINUE:.*]] unwind label %[[PAD]]
@@ -179,7 +178,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.destroy(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) personality i32 0 {
; CHECK-NEXT: [[ENTRY_DESTROY:.*:]]
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
; CHECK-NEXT: call void @free(ptr [[HDL]])
; CHECK-NEXT: ret void
;
@@ -187,7 +186,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.cleanup(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) personality i32 0 {
; CHECK-NEXT: [[ENTRY_CLEANUP:.*:]]
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
; CHECK-NEXT: call void @free(ptr null)
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Coroutines/coro-await-suspend-lower.ll b/llvm/test/Transforms/Coroutines/coro-await-suspend-lower.ll
index 01d3c90ef466c..05bac14f26a2d 100644
--- a/llvm/test/Transforms/Coroutines/coro-await-suspend-lower.ll
+++ b/llvm/test/Transforms/Coroutines/coro-await-suspend-lower.ll
@@ -86,12 +86,11 @@ declare void @free(ptr)
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr @f, ptr @f.resumers)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 24)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
-; CHECK-NEXT: [[RESUME_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
-; CHECK-NEXT: store ptr @f.resume, ptr [[RESUME_ADDR]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 0
-; CHECK-NEXT: [[INDEX_ADDR12:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
+; CHECK-NEXT: [[INDEX_ADDR12:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 0, ptr [[INDEX_ADDR12]], align 1
; CHECK-NEXT: ret void
;
@@ -99,8 +98,8 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*]]:
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
-; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
+; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[INDEX:%.*]] = load i2, ptr [[INDEX_ADDR]], align 1
; CHECK-NEXT: switch i2 [[INDEX]], label %[[UNREACHABLE:.*]] [
; CHECK-NEXT: i2 0, label %[[COROSAVE1:.*]]
@@ -109,7 +108,7 @@ declare void @free(ptr)
; CHECK-NEXT: i2 -1, label %[[CLEANUP:.*]]
; CHECK-NEXT: ]
; CHECK: [[COROSAVE1]]:
-; CHECK-NEXT: [[INDEX_ADDR13:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR13:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 1, ptr [[INDEX_ADDR13]], align 1
; CHECK-NEXT: call void @await_suspend_wrapper_void(ptr [[AWAITER_RELOAD_ADDR]], ptr [[HDL]])
; CHECK-NEXT: br label %[[AFTERCOROSUSPEND3]]
@@ -118,7 +117,7 @@ declare void @free(ptr)
; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[TMP0]], 0
; CHECK-NEXT: br i1 [[COND]], label %[[COROSAVE4:.*]], label %[[COROEND:.*]]
; CHECK: [[COROSAVE4]]:
-; CHECK-NEXT: [[INDEX_ADDR14:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR14:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 -2, ptr [[INDEX_ADDR14]], align 1
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @await_suspend_wrapper_bool(ptr [[AWAITER_RELOAD_ADDR]], ptr [[HDL]])
; CHECK-NEXT: br i1 [[TMP1]], label %[[AFTERCOROSUSPEND7]], label %[[COROSAVE8:.*]]
@@ -127,7 +126,7 @@ declare void @free(ptr)
; CHECK-NEXT: [[COND1:%.*]] = icmp eq i8 [[TMP2]], 0
; CHECK-NEXT: br i1 [[COND1]], label %[[COROSAVE8]], label %[[COROEND]]
; CHECK: [[COROSAVE8]]:
-; CHECK-NEXT: [[INDEX_ADDR15:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR15:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i2 -1, ptr [[INDEX_ADDR15]], align 1
; CHECK-NEXT: [[TMP3:%.*]] = call ptr @await_suspend_wrapper_handle(ptr [[AWAITER_RELOAD_ADDR]], ptr [[HDL]])
; CHECK-NEXT: [[TMP4:%.*]] = call ptr @llvm.coro.subfn.addr(ptr [[TMP3]], i8 0)
@@ -145,7 +144,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.destroy(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_DESTROY:.*:]]
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
; CHECK-NEXT: call void @free(ptr [[HDL]])
; CHECK-NEXT: ret void
;
@@ -153,7 +152,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.cleanup(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_CLEANUP:.*:]]
-; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 0
+; CHECK-NEXT: [[AWAITER_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 0
; CHECK-NEXT: call void @free(ptr null)
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Coroutines/coro-byval-param.ll b/llvm/test/Transforms/Coroutines/coro-byval-param.ll
index ead86322662e7..db1f151b59bc5 100644
--- a/llvm/test/Transforms/Coroutines/coro-byval-param.ll
+++ b/llvm/test/Transforms/Coroutines/coro-byval-param.ll
@@ -1,13 +1,14 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
%promise_type = type { i8 }
%struct.A = type <{ i64, i64, i32, [4 x i8] }>
; Check that the frame will contain 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: noinline ssp uwtable mustprogress
define ptr @foo(ptr nocapture readonly byval(%struct.A) align 8 %a1) #0 {
; CHECK-LABEL: define ptr @foo(
@@ -24,15 +25,14 @@ define ptr @foo(ptr nocapture readonly byval(%struct.A) align 8 %a1) #0 {
; CHECK-NEXT: [[TMP3:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[TMP0]], ptr [[TMP2]])
; CHECK-NEXT: store ptr @foo.resume, ptr [[TMP3]], align 8
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], ptr @foo.destroy, ptr @foo.cleanup
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[FOO_FRAME:%.*]], ptr [[TMP3]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 8
; CHECK-NEXT: store ptr [[TMP4]], ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[__PROMISE_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[TMP3]], i32 0, i32 2
-; CHECK-NEXT: [[A1_SPILL_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[TMP3]], i32 0, i32 5
-; CHECK-NEXT: [[TMP5:%.*]] = load [[STRUCT_A]], ptr [[A1]], align 1
-; CHECK-NEXT: store [[STRUCT_A]] [[TMP5]], ptr [[A1_SPILL_ADDR]], align 8
+; CHECK-NEXT: [[__PROMISE_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 16
+; CHECK-NEXT: [[A1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 24
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[A1_SPILL_ADDR]], ptr align 8 [[A1]], i64 24, i1 false)
; CHECK-NEXT: [[CALL2:%.*]] = call ptr @_ZN4task12promise_type17get_return_objectEv(ptr nonnull dereferenceable(1) [[__PROMISE_RELOAD_ADDR]])
; CHECK-NEXT: call void @initial_suspend(ptr nonnull dereferenceable(1) [[__PROMISE_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds nuw [[FOO_FRAME]], ptr [[TMP3]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP3]], i64 17
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: call fastcc void @_ZNSt12experimental13coroutines_v116coroutine_handleIN4task12promise_typeEE12from_addressEPv(ptr [[TMP3]]) #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret ptr [[CALL2]]
diff --git a/llvm/test/Transforms/Coroutines/coro-catchswitch.ll b/llvm/test/Transforms/Coroutines/coro-catchswitch.ll
index ec55954cea194..1fcf36f4f7ea9 100644
--- a/llvm/test/Transforms/Coroutines/coro-catchswitch.ll
+++ b/llvm/test/Transforms/Coroutines/coro-catchswitch.ll
@@ -13,7 +13,7 @@ define void @f(i1 %cond) presplitcoroutine personality i32 0 {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 16)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 4
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 4
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 4
; CHECK-NEXT: br i1 [[COND]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]]
; CHECK: [[IF_THEN]]:
@@ -25,7 +25,7 @@ define void @f(i1 %cond) presplitcoroutine personality i32 0 {
; CHECK: [[CATCH_DISPATCH]]:
; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ 1, %[[IF_THEN]] ], [ 2, %[[IF_ELSE]] ]
; CHECK-NEXT: [[TMP0:%.*]] = cleanuppad within none []
-; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store i32 [[VAL]], ptr [[VAL_SPILL_ADDR]], align 4
; CHECK-NEXT: cleanupret from [[TMP0]] unwind label %[[BB1:.*]]
; CHECK: [[BB1]]:
@@ -34,7 +34,7 @@ define void @f(i1 %cond) presplitcoroutine personality i32 0 {
; CHECK-NEXT: [[PAD:%.*]] = catchpad within [[SWITCH]] [ptr null, i32 64, ptr null]
; CHECK-NEXT: catchret from [[PAD]] to label %[[COROSAVE:.*]]
; CHECK: [[COROSAVE]]:
-; CHECK-NEXT: [[INDEX_ADDR3:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR3:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 12
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR3]], align 1
; CHECK-NEXT: br i1 false, label %[[RESUME:.*]], label %[[AFTERCOROEND]]
; CHECK: [[RESUME]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
index 4983ab4b47922..713e36c1f8fc9 100644
--- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-01.ll
@@ -77,15 +77,15 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @g.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[G_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @g.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[Y_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[Y_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i32 [[Y]], ptr [[Y_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[X_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[X_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i32 [[X]], ptr [[X_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[COND_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[COND_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: store i1 [[COND]], ptr [[COND_SPILL_ADDR]], align 1
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[G_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
@@ -93,7 +93,7 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-LABEL: define internal fastcc void @g.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(32) [[HDL:%.*]]) personality i32 0 {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[COND_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[COND_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: [[COND_RELOAD:%.*]] = load i1, ptr [[COND_RELOAD_ADDR]], align 1
; CHECK-NEXT: br i1 [[COND_RELOAD]], label %[[INVOKE1:.*]], label %[[INVOKE2:.*]]
; CHECK: [[INVOKE1]]:
@@ -104,12 +104,12 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-NEXT: to label %[[UNREACH]] unwind label %[[PAD_WITH_PHI_FROM_INVOKE2:.*]]
; CHECK: [[PAD_WITH_PHI_FROM_INVOKE2]]:
; CHECK-NEXT: [[TMP0:%.*]] = cleanuppad within none []
-; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: [[Y_RELOAD:%.*]] = load i32, ptr [[Y_RELOAD_ADDR]], align 4
; CHECK-NEXT: cleanupret from [[TMP0]] unwind label %[[PAD_WITH_PHI:.*]]
; CHECK: [[PAD_WITH_PHI_FROM_INVOKE1]]:
; CHECK-NEXT: [[TMP1:%.*]] = cleanuppad within none []
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[X_RELOAD:%.*]] = load i32, ptr [[X_RELOAD_ADDR]], align 4
; CHECK-NEXT: cleanupret from [[TMP1]] unwind label %[[PAD_WITH_PHI]]
; CHECK: [[PAD_WITH_PHI]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
index a005a9c8e6167..335b9e5cd7945 100644
--- a/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-eh-aware-edge-split-02.ll
@@ -77,15 +77,15 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @h.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[H_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @h.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[Y_SPILL_ADDR:%.*]] = getelementptr inbounds [[H_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[Y_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i32 [[Y]], ptr [[Y_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[X_SPILL_ADDR:%.*]] = getelementptr inbounds [[H_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[X_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i32 [[X]], ptr [[X_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[COND_SPILL_ADDR:%.*]] = getelementptr inbounds [[H_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[COND_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: store i1 [[COND]], ptr [[COND_SPILL_ADDR]], align 1
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[H_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
@@ -93,7 +93,7 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-LABEL: define internal fastcc void @h.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(32) [[HDL:%.*]]) personality i32 0 {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[COND_RELOAD_ADDR:%.*]] = getelementptr inbounds [[H_FRAME:%.*]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[COND_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 25
; CHECK-NEXT: [[COND_RELOAD:%.*]] = load i1, ptr [[COND_RELOAD_ADDR]], align 1
; CHECK-NEXT: br i1 [[COND_RELOAD]], label %[[INVOKE1:.*]], label %[[INVOKE2:.*]]
; CHECK: [[INVOKE1]]:
@@ -104,12 +104,12 @@ declare ptr @llvm.coro.free(token, ptr nocapture readonly)
; CHECK-NEXT: to label %[[COROEND]] unwind label %[[PAD_WITH_PHI_FROM_INVOKE2:.*]]
; CHECK: [[PAD_WITH_PHI_FROM_INVOKE2]]:
; CHECK-NEXT: [[TMP0:%.*]] = cleanuppad within none []
-; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds [[H_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[Y_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: [[Y_RELOAD:%.*]] = load i32, ptr [[Y_RELOAD_ADDR]], align 4
; CHECK-NEXT: cleanupret from [[TMP0]] unwind label %[[PAD_WITH_PHI:.*]]
; CHECK: [[PAD_WITH_PHI_FROM_INVOKE1]]:
; CHECK-NEXT: [[TMP1:%.*]] = cleanuppad within none []
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[H_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[X_RELOAD:%.*]] = load i32, ptr [[X_RELOAD_ADDR]], align 4
; CHECK-NEXT: cleanupret from [[TMP1]] unwind label %[[PAD_WITH_PHI]]
; CHECK: [[PAD_WITH_PHI]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll b/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
index 99adb44349aa7..d0e1f32f12af8 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-arrayalloca.ll
@@ -58,15 +58,15 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 56)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[PREFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4, i32 0
-; CHECK-NEXT: [[SUFFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[PREFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
+; CHECK-NEXT: [[SUFFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: call void @consume.double.ptr(ptr [[PREFIX_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume.i32.ptr(ptr [[DATA_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume.double.ptr(ptr [[SUFFIX_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 48
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -74,9 +74,9 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(56) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[PREFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4, i32 0
-; CHECK-NEXT: [[SUFFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[PREFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
+; CHECK-NEXT: [[SUFFIX_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: call void @consume.double.ptr(ptr [[PREFIX_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume.i32.ptr(ptr [[DATA_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume.double.ptr(ptr [[SUFFIX_RELOAD_ADDR]])
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
index 3bed01bb4a877..077c01f11c9af 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-01.ll
@@ -4,7 +4,8 @@
; There should be only one %struct.big_structure in the frame.
; RUN: opt < %s -passes='cgscc(coro-split<reuse-storage>),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", %struct.big_structure, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
@@ -18,18 +19,18 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.coro.id(i32 16, ptr nonnull null, ptr @a, ptr @a.resumers)
; CHECK-NEXT: [[TMP1:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[TMP0]], ptr null)
; CHECK-NEXT: store ptr @a.resume, ptr [[TMP1]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[A_FRAME:%.*]], ptr [[TMP1]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 8
; CHECK-NEXT: store ptr @a.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds [[A_FRAME]], ptr [[TMP1]], i32 0, i32 3
+; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
index 87fea63ce0b39..b4cc57c24f0d8 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-02.ll
@@ -3,7 +3,8 @@
; re-use the same slot in Coroutine frame.
; RUN: opt < %s -passes='cgscc(coro-split<reuse-storage>),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", %struct.big_structure, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
@@ -19,18 +20,18 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.coro.id(i32 16, ptr nonnull null, ptr @a, ptr @a.resumers)
; CHECK-NEXT: [[TMP1:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[TMP0]], ptr null)
; CHECK-NEXT: store ptr @a.resume, ptr [[TMP1]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[A_FRAME:%.*]], ptr [[TMP1]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 8
; CHECK-NEXT: store ptr @a.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds [[A_FRAME]], ptr [[TMP1]], i32 0, i32 3
+; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume.2(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
index db2458c71a731..533525b691350 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-04.ll
@@ -3,7 +3,8 @@
; range is not overlapping each other should not re-use the same slot in Coroutine frame.
; RUN: opt < %s -passes='cgscc(coro-split<reuse-storage>),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", %struct.big_structure, i1, [26 x i8], %struct.big_structure.2 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
@@ -19,19 +20,19 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.coro.id(i32 16, ptr nonnull null, ptr @a, ptr @a.resumers)
; CHECK-NEXT: [[TMP1:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[TMP0]], ptr null)
; CHECK-NEXT: store ptr @a.resume, ptr [[TMP1]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[A_FRAME:%.*]], ptr [[TMP1]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 8
; CHECK-NEXT: store ptr @a.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds [[A_FRAME]], ptr [[TMP1]], i32 0, i32 3
-; CHECK-NEXT: [[B_RELOAD_ADDR:%.*]] = getelementptr inbounds [[A_FRAME]], ptr [[TMP1]], i32 0, i32 6
+; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
+; CHECK-NEXT: [[B_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 544
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume.2(ptr nonnull [[B_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 517
; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
index 1815df83b227b..b78e448b880d6 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame-reuse-alloca-05.ll
@@ -3,7 +3,8 @@
; lifetime range is not overlapping each other re-use the same slot in CorotuineFrame.
; RUN: opt < %s -passes='cgscc(coro-split<reuse-storage>),simplifycfg,early-cse' -S | FileCheck %s
-; CHECK: %a.Frame = type { ptr, ptr, %"struct.task::promise_type", i1, [14 x i8], %struct.big_structure }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
%"struct.task::promise_type" = type { i8 }
%struct.awaitable = type { i8 }
@@ -19,18 +20,18 @@ define void @a(i1 zeroext %cond) presplitcoroutine {
; CHECK-NEXT: [[TMP0:%.*]] = call token @llvm.coro.id(i32 16, ptr nonnull null, ptr @a, ptr @a.resumers)
; CHECK-NEXT: [[TMP1:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[TMP0]], ptr null)
; CHECK-NEXT: store ptr @a.resume, ptr [[TMP1]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[A_FRAME:%.*]], ptr [[TMP1]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 8
; CHECK-NEXT: store ptr @a.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds [[A_FRAME]], ptr [[TMP1]], i32 0, i32 5
+; CHECK-NEXT: [[A_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 32
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: call void @consume(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: call void @consume.2(ptr nonnull [[A_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds nuw [[A_FRAME]], ptr [[TMP1]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 17
; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR5]], align 1
; CHECK-NEXT: br label %[[AFTERCOROEND]]
; CHECK: [[AFTERCOROEND]]:
diff --git a/llvm/test/Transforms/Coroutines/coro-frame.ll b/llvm/test/Transforms/Coroutines/coro-frame.ll
index 7f12362cd48ae..1beccdf5de7b0 100644
--- a/llvm/test/Transforms/Coroutines/coro-frame.ll
+++ b/llvm/test/Transforms/Coroutines/coro-frame.ll
@@ -60,14 +60,14 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 40)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[THIS1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[THIS1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i64 [[THIS]], ptr [[THIS1_SPILL_ADDR]], align 4
; CHECK-NEXT: [[R:%.*]] = call double @print(double 0.000000e+00)
-; CHECK-NEXT: [[R_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[R_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store double [[R]], ptr [[R_SPILL_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -75,9 +75,9 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[HDL:%.*]]) personality i32 0 {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[R_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[R_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[R_RELOAD:%.*]] = load double, ptr [[R_RELOAD_ADDR]], align 8
-; CHECK-NEXT: [[THIS1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[THIS1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: [[THIS1_RELOAD:%.*]] = load i64, ptr [[THIS1_RELOAD_ADDR]], align 4
; CHECK-NEXT: [[TMP0:%.*]] = call double @print(double [[R_RELOAD]])
; CHECK-NEXT: call void @print2(i64 [[THIS1_RELOAD]])
diff --git a/llvm/test/Transforms/Coroutines/coro-lifetime-end.ll b/llvm/test/Transforms/Coroutines/coro-lifetime-end.ll
index 503b93ea76a02..83137a15cd16e 100644
--- a/llvm/test/Transforms/Coroutines/coro-lifetime-end.ll
+++ b/llvm/test/Transforms/Coroutines/coro-lifetime-end.ll
@@ -17,11 +17,11 @@ define void @HasNoLifetimeEnd() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @HasNoLifetimeEnd.resume, ptr [[VFRAME]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[HASNOLIFETIMEEND_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @HasNoLifetimeEnd.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds [[HASNOLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
; CHECK-NEXT: call void @consume.i8.array(ptr [[INDEX_ADDR1]])
-; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds nuw [[HASNOLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 116
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
; CHECK-NEXT: ret void
;
@@ -54,11 +54,11 @@ define void @LifetimeEndAfterCoroEnd() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @LifetimeEndAfterCoroEnd.resume, ptr [[VFRAME]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[LIFETIMEENDAFTERCOROEND_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @LifetimeEndAfterCoroEnd.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds [[LIFETIMEENDAFTERCOROEND_FRAME]], ptr [[VFRAME]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
; CHECK-NEXT: call void @consume.i8.array(ptr [[INDEX_ADDR1]])
-; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds nuw [[LIFETIMEENDAFTERCOROEND_FRAME]], ptr [[VFRAME]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 116
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
; CHECK-NEXT: ret void
;
@@ -92,12 +92,12 @@ define void @BranchWithoutLifetimeEnd() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i64 16)
; CHECK-NEXT: [[VFRAME:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @BranchWithoutLifetimeEnd.resume, ptr [[VFRAME]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[BRANCHWITHOUTLIFETIMEEND_FRAME:%.*]], ptr [[VFRAME]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 8
; CHECK-NEXT: store ptr @BranchWithoutLifetimeEnd.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[TESTVAL:%.*]] = getelementptr inbounds [[BRANCHWITHOUTLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 2
+; CHECK-NEXT: [[TESTVAL:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 16
; CHECK-NEXT: call void @consume.i8.array(ptr [[TESTVAL]])
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr @testbool, align 1
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[BRANCHWITHOUTLIFETIMEEND_FRAME]], ptr [[VFRAME]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[VFRAME]], i64 116
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Coroutines/coro-noop.ll b/llvm/test/Transforms/Coroutines/coro-noop.ll
index de92df6b9f90b..0f61db42c5dec 100644
--- a/llvm/test/Transforms/Coroutines/coro-noop.ll
+++ b/llvm/test/Transforms/Coroutines/coro-noop.ll
@@ -1,7 +1,6 @@
; Tests that CoroCleanup pass correctly lowers coro.noop
; RUN: opt < %s -S -passes=coro-cleanup | FileCheck %s
-; CHECK: %NoopCoro.Frame = type { ptr, ptr }
; CHECK: @NoopCoro.Frame.Const = private constant %NoopCoro.Frame { ptr @__NoopCoro_ResumeDestroy, ptr @__NoopCoro_ResumeDestroy }
diff --git a/llvm/test/Transforms/Coroutines/coro-padding.ll b/llvm/test/Transforms/Coroutines/coro-padding.ll
index 9e4d5d95209ad..c8749bc43db8e 100644
--- a/llvm/test/Transforms/Coroutines/coro-padding.ll
+++ b/llvm/test/Transforms/Coroutines/coro-padding.ll
@@ -49,14 +49,14 @@ declare void @free(ptr)
; CHECK-LABEL: define ptr @f() {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[ID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr @f.resumers)
-; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 40)
+; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 64)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: call void @consume(ptr [[DATA_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -64,7 +64,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 32 dereferenceable(64) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: call void @consume(ptr [[DATA_RELOAD_ADDR]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Coroutines/coro-param-copy.ll b/llvm/test/Transforms/Coroutines/coro-param-copy.ll
index 4f490befafd1e..10a0ed2deedc4 100644
--- a/llvm/test/Transforms/Coroutines/coro-param-copy.ll
+++ b/llvm/test/Transforms/Coroutines/coro-param-copy.ll
@@ -8,7 +8,8 @@
; 3. Then see that we only copy the x as y was not modified prior to
; coro.begin.
-; CHECK: %f.Frame = type { ptr, ptr, i64, i64, i64, i64, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f() presplitcoroutine {
; CHECK-LABEL: define ptr @f() {
@@ -27,17 +28,15 @@ define ptr @f() presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @myAlloc(i32 56)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
-; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[X_ADDR]], align 4
-; CHECK-NEXT: store i64 [[TMP1]], ptr [[TMP0]], align 4
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
-; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[Z_ADDR]], align 4
-; CHECK-NEXT: store i64 [[TMP3]], ptr [[TMP2]], align 4
-; CHECK-NEXT: [[Y_ADDR_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP0]], ptr align 8 [[X_ADDR]], i64 8, i1 false)
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 40
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP1]], ptr align 8 [[Z_ADDR]], i64 8, i1 false)
+; CHECK-NEXT: [[Y_ADDR_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 32
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr [[Y_ADDR_RELOAD_ADDR]], i8 1, i32 4, i1 false)
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 6
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 48
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll
index 026e23913d647..74a3f8d449d0c 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll
@@ -157,7 +157,7 @@ declare void @print(i32)
;
; CHECK-LABEL: @g(
; CHECK-NEXT: PostSpill:
-; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 16)
+; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 12)
; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8
; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8
; CHECK-NEXT: store i32 [[VAL:%.*]], ptr [[VAL_SPILL_ADDR]], align 4
diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
index aad762e2c9335..bf95b2a74e6de 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll
@@ -84,9 +84,9 @@ declare fastcc void @deallocate(ptr %ptr)
declare void @print(i32)
; CHECK-LABEL: @f(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 16)
+; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 12)
; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 1
+; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8
; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8
; CHECK-NEXT: [[OLDVALUE:%.*]] = load i32, ptr [[PTR]], align 4
; CHECK-NEXT: store i32 [[OLDVALUE]], ptr [[TEMP]], align 4
@@ -97,7 +97,7 @@ declare void @print(i32)
; CHECK-LABEL: @f.resume.0(
; CHECK-NEXT: entryresume.0:
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1
+; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8
; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CONT:%.*]]
; CHECK: cont:
; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8
@@ -111,10 +111,10 @@ declare void @print(i32)
;
; CHECK-LABEL: @g(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 16)
+; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 13)
; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 1
-; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[TMP0]], i32 0, i32 2
+; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8
+; CHECK-NEXT: [[VAL_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 12
; CHECK-NEXT: store i8 [[VAL:%.*]], ptr [[VAL_SPILL_ADDR]], align 1
; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8
; CHECK-NEXT: [[OLDVALUE:%.*]] = load i32, ptr [[PTR]], align 4
@@ -126,7 +126,7 @@ declare void @print(i32)
; CHECK-LABEL: @g.resume.0(
; CHECK-NEXT: entryresume.0:
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1
+; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8
; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[CLEANUP:%.*]], label [[CONT:%.*]]
; CHECK: cont:
; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8
@@ -134,7 +134,7 @@ declare void @print(i32)
; CHECK-NEXT: store i32 [[NEWVALUE]], ptr [[PTR_RELOAD]], align 4
; CHECK-NEXT: br label [[CLEANUP]]
; CHECK: cleanup:
-; CHECK-NEXT: [[VAL_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[TMP2]], i32 0, i32 2
+; CHECK-NEXT: [[VAL_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 12
; CHECK-NEXT: [[VAL_RELOAD:%.*]] = load i8, ptr [[VAL_RELOAD_ADDR]], align 1
; CHECK-NEXT: call fastcc void @deallocate(ptr [[TMP2]])
; CHECK-NEXT: ret i8 [[VAL_RELOAD]]
@@ -142,9 +142,9 @@ declare void @print(i32)
;
; CHECK-LABEL: @h(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 16)
+; CHECK-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 12)
; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[H_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 1
+; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8
; CHECK-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8
; CHECK-NEXT: [[OLDVALUE:%.*]] = load i32, ptr [[PTR]], align 4
; CHECK-NEXT: store i32 [[OLDVALUE]], ptr [[TEMP]], align 4
@@ -155,7 +155,7 @@ declare void @print(i32)
; CHECK-LABEL: @h.resume.0(
; CHECK-NEXT: entryresume.0:
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
-; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds [[H_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1
+; CHECK-NEXT: [[TEMP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8
; CHECK-NEXT: br i1 [[TMP1:%.*]], label [[COROEND:%.*]], label [[CONT:%.*]]
; CHECK: cont:
; CHECK-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[TMP2]], align 8
diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll
index eeba55b8f23a4..ed680adb48eef 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-remat.ll
@@ -4,14 +4,14 @@
; RUN: opt < %s -O0 -S | FileCheck %s
-; CHECK: %f.Frame = type { i32 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define { ptr, i32 } @f(ptr %buffer, i32 %n) {
; CHECK-LABEL: define { ptr, i32 } @f(
; CHECK-SAME: ptr [[BUFFER:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[BUFFER]], i32 0, i32 0
-; CHECK-NEXT: store i32 [[N]], ptr [[N_VAL_SPILL_ADDR]], align 4
+; CHECK-NEXT: store i32 [[N]], ptr [[BUFFER]], align 4
; CHECK-NEXT: call void @print(i32 [[N]])
; CHECK-NEXT: [[INC1:%.*]] = add i32 [[N]], 1
; CHECK-NEXT: [[INC2:%.*]] = add i32 [[INC1]], 2
diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
index a19c1ca0e7f3a..b1dfbd1b6d4f6 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon-resume-values2.ll
@@ -44,11 +44,11 @@ declare void @print(i32)
; CHECK-LABEL: @f.resume.0(
; CHECK-NEXT: entryresume.0:
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
-; CHECK-NEXT: [[VALUE0_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 1
+; CHECK-NEXT: [[VALUE0_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 4
; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[VALUE0_SPILL_ADDR]], align 4
; CHECK-NEXT: [[N_RELOAD:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: [[SUM0:%.*]] = call i32 @add(i32 [[N_RELOAD]], i32 [[TMP1]])
-; CHECK-NEXT: [[SUM0_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 2
+; CHECK-NEXT: [[SUM0_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8
; CHECK-NEXT: store i32 [[SUM0]], ptr [[SUM0_SPILL_ADDR]], align 4
; CHECK-NEXT: ret ptr @f.resume.1
;
@@ -56,15 +56,15 @@ declare void @print(i32)
; CHECK-LABEL: @f.resume.1(
; CHECK-NEXT: entryresume.1:
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
-; CHECK-NEXT: [[VALUE1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 3
+; CHECK-NEXT: [[VALUE1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 12
; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[VALUE1_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[SUM0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 2
+; CHECK-NEXT: [[SUM0_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8
; CHECK-NEXT: [[SUM0_RELOAD:%.*]] = load i32, ptr [[SUM0_RELOAD_ADDR]], align 4
-; CHECK-NEXT: [[VALUE0_RELOAD_ADDR5:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 1
+; CHECK-NEXT: [[VALUE0_RELOAD_ADDR5:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 4
; CHECK-NEXT: [[VALUE0_RELOAD6:%.*]] = load i32, ptr [[VALUE0_RELOAD_ADDR5]], align 4
; CHECK-NEXT: [[SUM1:%.*]] = call i32 @add(i32 [[SUM0_RELOAD]], i32 [[VALUE0_RELOAD6]])
; CHECK-NEXT: [[SUM2:%.*]] = call i32 @add(i32 [[SUM1]], i32 [[TMP1]])
-; CHECK-NEXT: [[SUM2_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 4
+; CHECK-NEXT: [[SUM2_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 16
; CHECK-NEXT: store i32 [[SUM2]], ptr [[SUM2_SPILL_ADDR]], align 4
; CHECK-NEXT: ret ptr @f.resume.2
;
@@ -72,11 +72,11 @@ declare void @print(i32)
; CHECK-LABEL: @f.resume.2(
; CHECK-NEXT: entryresume.2:
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8
-; CHECK-NEXT: [[SUM2_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[TMP2]], i32 0, i32 4
+; CHECK-NEXT: [[SUM2_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 16
; CHECK-NEXT: [[SUM2_RELOAD:%.*]] = load i32, ptr [[SUM2_RELOAD_ADDR]], align 4
-; CHECK-NEXT: [[VALUE1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 3
+; CHECK-NEXT: [[VALUE1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 12
; CHECK-NEXT: [[VALUE1_RELOAD:%.*]] = load i32, ptr [[VALUE1_RELOAD_ADDR]], align 4
-; CHECK-NEXT: [[VALUE0_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[TMP2]], i32 0, i32 1
+; CHECK-NEXT: [[VALUE0_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 4
; CHECK-NEXT: [[VALUE0_RELOAD:%.*]] = load i32, ptr [[VALUE0_RELOAD_ADDR]], align 4
; CHECK-NEXT: [[SUM3:%.*]] = call i32 @add(i32 [[SUM2_RELOAD]], i32 [[VALUE0_RELOAD]])
; CHECK-NEXT: [[SUM4:%.*]] = call i32 @add(i32 [[SUM3]], i32 [[VALUE1_RELOAD]])
diff --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll
index 86eba3b5d134f..d36ff5271bc71 100644
--- a/llvm/test/Transforms/Coroutines/coro-retcon.ll
+++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll
@@ -12,8 +12,7 @@ define ptr @f(ptr %buffer, i32 %n) {
;
; CORO-LABEL: @f(
; CORO-NEXT: entry:
-; CORO-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[BUFFER:%.*]], i32 0, i32 0
-; CORO-NEXT: store i32 [[N:%.*]], ptr [[N_VAL_SPILL_ADDR]], align 4
+; CORO-NEXT: store i32 [[N:%.*]], ptr [[N_VAL_SPILL_ADDR:%.*]], align 4
; CORO-NEXT: call void @print(i32 [[N]])
; CORO-NEXT: ret ptr @f.resume.0
;
@@ -84,9 +83,8 @@ define hidden { ptr, ptr } @g(ptr %buffer, ptr %ptr) {
; CORO-NEXT: entry:
; CORO-NEXT: [[TMP0:%.*]] = call ptr @allocate(i32 8)
; CORO-NEXT: store ptr [[TMP0]], ptr [[BUFFER:%.*]], align 8
-; CORO-NEXT: [[PTR_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[TMP0]], i32 0, i32 0
-; CORO-NEXT: store ptr [[PTR:%.*]], ptr [[PTR_SPILL_ADDR]], align 8
-; CORO-NEXT: [[PTR_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], ptr [[TMP0]], i32 0, i32 0
+; CORO-NEXT: store ptr [[PTR:%.*]], ptr [[TMP0]], align 8
+; CORO-NEXT: [[PTR_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 0
; CORO-NEXT: [[PTR_RELOAD:%.*]] = load ptr, ptr [[PTR_RELOAD_ADDR]], align 8
; CORO-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr } poison, ptr @g.resume.0, 0
; CORO-NEXT: [[TMP2:%.*]] = insertvalue { ptr, ptr } [[TMP1]], ptr [[PTR_RELOAD]], 1
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll b/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
index 6694fa79b8858..c983e063a2965 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-after-phi.ll
@@ -4,7 +4,6 @@
; Verifies that the both phis are stored correctly in the coroutine frame
-; CHECK: %f.Frame = type { ptr, ptr, i32, i32, i1 }
define ptr @f(i1 %n) presplitcoroutine {
; CHECK-LABEL: @f(
@@ -13,15 +12,15 @@ define ptr @f(i1 %n) presplitcoroutine {
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[N:%.*]], i32 0, i32 2
; CHECK-NEXT: [[SPEC_SELECT5:%.*]] = select i1 [[N]], i32 1, i32 3
-; CHECK-NEXT: [[PHI2_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[PHI2_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i32 [[SPEC_SELECT5]], ptr [[PHI2_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[PHI1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[PHI1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i32 [[SPEC_SELECT]], ptr [[PHI1_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll b/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
index 1ef841faeab11..7a62885ec37ea 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-corobegin.ll
@@ -58,13 +58,13 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 32)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
; CHECK-NEXT: [[INNERID:%.*]] = call token @llvm.coro.id(i32 0, ptr null, ptr @g, ptr @g.resumers)
; CHECK-NEXT: [[INNERHDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[INNERID]], ptr null)
-; CHECK-NEXT: [[INNERHDL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INNERHDL_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store ptr [[INNERHDL]], ptr [[INNERHDL_SPILL_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -72,7 +72,7 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(32) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[INNERHDL_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INNERHDL_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[INNERHDL_RELOAD:%.*]] = load ptr, ptr [[INNERHDL_RELOAD_ADDR]], align 8
; CHECK-NEXT: [[GVAR_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], ptr [[INNERHDL_RELOAD]], i32 0, i32 4
; CHECK-NEXT: [[GVAR:%.*]] = load i32, ptr [[GVAR_ADDR]], align 4
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll b/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
index 7f14693052bd0..0c3b9aa49c919 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-defs-before-corobegin.ll
@@ -2,7 +2,8 @@
; Verifies that phi and invoke definitions before CoroBegin are spilled properly.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s
-; CHECK: %f.Frame = type { ptr, ptr, i32, i32, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
define ptr @f(i1 %n) presplitcoroutine personality i32 0 {
; CHECK-LABEL: define ptr @f(
@@ -15,15 +16,15 @@ define ptr @f(i1 %n) presplitcoroutine personality i32 0 {
; CHECK-NEXT: [[VALUE_INVOKE:%.*]] = call i32 @calc()
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[VALUE_INVOKE_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[VALUE_INVOKE_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i32 [[VALUE_INVOKE]], ptr [[VALUE_INVOKE_SPILL_ADDR]], align 4
-; CHECK-NEXT: [[VALUE_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[VALUE_PHI_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i32 [[SPEC_SELECT]], ptr [[VALUE_PHI_SPILL_ADDR]], align 4
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @print(i32 [[SPEC_SELECT]])
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @print(i32 [[VALUE_INVOKE]])
-; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR2:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 24
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR2]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll b/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll
index 248dc9c1f7247..1211873500430 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-promise-02.ll
@@ -60,14 +60,13 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 128)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
-; CHECK-NEXT: [[TMP1:%.*]] = load %"class.task::promise_type", ptr [[__PROMISE]], align 1
-; CHECK-NEXT: store %"class.task::promise_type" [[TMP1]], ptr [[TMP0]], align 1
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 64
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[TMP0]], ptr align 64 [[__PROMISE]], i64 64, i1 false)
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: call void @consume(ptr [[DATA_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -75,8 +74,8 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 64 dereferenceable(128) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[__PROMISE_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[__PROMISE_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 64
; CHECK-NEXT: call void @consume(ptr [[DATA_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume2(ptr [[__PROMISE_RELOAD_ADDR]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-promise.ll b/llvm/test/Transforms/Coroutines/coro-spill-promise.ll
index f57b67174eeb5..530bfa3ec1d48 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-promise.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-promise.ll
@@ -56,11 +56,11 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 128)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: call void @consume(ptr [[DATA_RELOAD_ADDR]])
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -68,8 +68,8 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 64 dereferenceable(128) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[__PROMISE_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 5
+; CHECK-NEXT: [[DATA_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[__PROMISE_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 64
; CHECK-NEXT: call void @consume(ptr [[DATA_RELOAD_ADDR]])
; CHECK-NEXT: call void @consume2(ptr [[__PROMISE_RELOAD_ADDR]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
diff --git a/llvm/test/Transforms/Coroutines/coro-spill-suspend.ll b/llvm/test/Transforms/Coroutines/coro-spill-suspend.ll
index 8f33724a2d12e..35fd078643c89 100644
--- a/llvm/test/Transforms/Coroutines/coro-spill-suspend.ll
+++ b/llvm/test/Transforms/Coroutines/coro-spill-suspend.ll
@@ -4,9 +4,7 @@
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
; %sp1 should be part of the frame (the i8 value).
-;
; If the coro resumes, %sp1 is set to 0.
-;
; In the coro destroy function, %sp1 is reloaded from the frame. Its value
; depends on whether the coroutine was resumed or not.
define ptr @f(i32 %n) presplitcoroutine {
@@ -52,11 +50,11 @@ declare void @free(ptr)
; CHECK-NEXT: [[ALLOC:%.*]] = call ptr @malloc(i32 24)
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[ALLOC]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr @f.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR4:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR4]], align 1
-; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: store i8 -1, ptr [[SP1_SPILL_ADDR]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -64,14 +62,14 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*]]:
-; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[INDEX:%.*]] = load i1, ptr [[INDEX_ADDR]], align 1
; CHECK-NEXT: switch i1 [[INDEX]], label %[[UNREACHABLE:.*]] [
; CHECK-NEXT: i1 false, label %[[AFTERCOROSUSPEND:.*]]
; CHECK-NEXT: i1 true, label %[[AFTERCOROSUSPEND3:.*]]
; CHECK-NEXT: ]
; CHECK: [[AFTERCOROSUSPEND]]:
-; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: store i8 0, ptr [[SP1_SPILL_ADDR]], align 1
; CHECK-NEXT: store i1 true, ptr [[INDEX_ADDR]], align 1
; CHECK-NEXT: br label %[[AFTERCOROSUSPEND3]]
@@ -80,7 +78,7 @@ declare void @free(ptr)
; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[TMP0]], 0
; CHECK-NEXT: br i1 [[COND]], label %[[CLEANUP:.*]], label %[[COROEND:.*]]
; CHECK: [[CLEANUP]]:
-; CHECK-NEXT: [[SP1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: [[SP1_RELOAD:%.*]] = load i8, ptr [[SP1_RELOAD_ADDR]], align 1
; CHECK-NEXT: call void @print(i8 [[SP1_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
@@ -94,18 +92,18 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.destroy(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_DESTROY:.*:]]
-; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[INDEX:%.*]] = load i1, ptr [[INDEX_ADDR]], align 1
; CHECK-NEXT: switch i1 [[INDEX]], label %[[UNREACHABLE:.*]] [
; CHECK-NEXT: i1 false, label %[[AFTERCOROSUSPEND:.*]]
; CHECK-NEXT: i1 true, label %[[CLEANUP:.*]]
; CHECK-NEXT: ]
; CHECK: [[AFTERCOROSUSPEND]]:
-; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: store i8 1, ptr [[SP1_SPILL_ADDR]], align 1
; CHECK-NEXT: br label %[[CLEANUP]]
; CHECK: [[CLEANUP]]:
-; CHECK-NEXT: [[SP1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: [[SP1_RELOAD:%.*]] = load i8, ptr [[SP1_RELOAD_ADDR]], align 1
; CHECK-NEXT: call void @print(i8 [[SP1_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
@@ -117,18 +115,18 @@ declare void @free(ptr)
; CHECK-LABEL: define internal fastcc void @f.cleanup(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_CLEANUP:.*:]]
-; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[INDEX_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: [[INDEX:%.*]] = load i1, ptr [[INDEX_ADDR]], align 1
; CHECK-NEXT: switch i1 [[INDEX]], label %[[UNREACHABLE:.*]] [
; CHECK-NEXT: i1 false, label %[[AFTERCOROSUSPEND:.*]]
; CHECK-NEXT: i1 true, label %[[CLEANUP:.*]]
; CHECK-NEXT: ]
; CHECK: [[AFTERCOROSUSPEND]]:
-; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: store i8 1, ptr [[SP1_SPILL_ADDR]], align 1
; CHECK-NEXT: br label %[[CLEANUP]]
; CHECK: [[CLEANUP]]:
-; CHECK-NEXT: [[SP1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[SP1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 17
; CHECK-NEXT: [[SP1_RELOAD:%.*]] = load i8, ptr [[SP1_RELOAD_ADDR]], align 1
; CHECK-NEXT: call void @print(i8 [[SP1_RELOAD]])
; CHECK-NEXT: call void @free(ptr null)
diff --git a/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll b/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll
index 12dfa16991326..0d0ea4991146d 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll
@@ -2,6 +2,8 @@
; Test that nested structs in coroutine frames have correct debug info scoping.
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
; Minimal nested struct types that used to trigger a scoping issue:
; we used to set the wrong `scope` for the `DIDerivedType` member entries of the `DICompositeType`
; as well as the `scope` for `DICompositeType` for the inner struct itself.
diff --git a/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll b/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
index 010c6b87b3c21..54a721b1365d8 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
@@ -69,12 +69,12 @@ declare void @free(ptr) willreturn allockind("free") "alloc-family"="malloc"
; CHECK-NEXT: [[HDL:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[ID]], ptr [[PHI]])
; CHECK-NEXT: store ptr @f.resume, ptr [[HDL]], align 8
; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[NEED_ALLOC]], ptr @f.destroy, ptr @f.cleanup
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 8
; CHECK-NEXT: store ptr [[TMP0]], ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[X_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME]], ptr [[HDL]], i32 0, i32 2
+; CHECK-NEXT: [[X_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
; CHECK-NEXT: store i32 [[X]], ptr [[X_SPILL_ADDR]], align 4
; CHECK-NEXT: call void @print(i32 0)
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[F_FRAME]], ptr [[HDL]], i32 0, i32 3
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 20
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret ptr [[HDL]]
;
@@ -82,8 +82,8 @@ declare void @free(ptr) willreturn allockind("free") "alloc-family"="malloc"
; CHECK-LABEL: define internal fastcc void @f.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], ptr [[HDL]], i32 0, i32 2
-; CHECK-NEXT: [[X_RELOAD:%.*]] = load i32, ptr [[X_RELOAD_ADDR]], align 4, !tbaa [[F_FRAME_SLOT_TBAA4:![0-9]+]]
+; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
+; CHECK-NEXT: [[X_RELOAD:%.*]] = load i32, ptr [[X_RELOAD_ADDR]], align 4, !tbaa [[F.FRAME_SLOT_TBAA4:![0-9]+]]
; CHECK-NEXT: call void @print(i32 [[X_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
; CHECK-NEXT: ret void
@@ -106,6 +106,6 @@ declare void @free(ptr) willreturn allockind("free") "alloc-family"="malloc"
; CHECK: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}
; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
; CHECK: [[META3]] = !{!"Simple C++ TBAA"}
-; CHECK: [[F_FRAME_SLOT_TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
+; CHECK: [[F.FRAME_SLOT_TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
; CHECK: [[META5]] = !{!"f.Frame Slot", [[META3]], i64 0}
;.
diff --git a/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll b/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
index 973015fd13aff..5a0de393007c0 100644
--- a/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
+++ b/llvm/test/Transforms/Coroutines/coro-zero-alloca.ll
@@ -60,9 +60,9 @@ cleanup: ; preds = %wakeup, %entry
; CHECK-NEXT: [[CORO_ALLOC:%.*]] = call ptr @malloc(i64 24)
; CHECK-NEXT: [[CORO_STATE:%.*]] = call noalias nonnull ptr @llvm.coro.begin(token [[CORO_ID]], ptr [[CORO_ALLOC]])
; CHECK-NEXT: store ptr @foo.resume, ptr [[CORO_STATE]], align 8
-; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds nuw [[FOO_FRAME:%.*]], ptr [[CORO_STATE]], i32 0, i32 1
+; CHECK-NEXT: [[DESTROY_ADDR:%.*]] = getelementptr inbounds i8, ptr [[CORO_STATE]], i64 8
; CHECK-NEXT: store ptr @foo.destroy, ptr [[DESTROY_ADDR]], align 8
-; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds nuw [[FOO_FRAME]], ptr [[CORO_STATE]], i32 0, i32 4
+; CHECK-NEXT: [[INDEX_ADDR1:%.*]] = getelementptr inbounds i8, ptr [[CORO_STATE]], i64 22
; CHECK-NEXT: store i1 false, ptr [[INDEX_ADDR1]], align 1
; CHECK-NEXT: ret void
;
@@ -70,8 +70,8 @@ cleanup: ; preds = %wakeup, %entry
; CHECK-LABEL: define internal fastcc void @foo.resume(
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[CORO_STATE:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
-; CHECK-NEXT: [[A1_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME:%.*]], ptr [[CORO_STATE]], i32 0, i32 2
-; CHECK-NEXT: [[A4_RELOAD_ADDR:%.*]] = getelementptr inbounds [[FOO_FRAME]], ptr [[CORO_STATE]], i32 0, i32 3
+; CHECK-NEXT: [[A1_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[CORO_STATE]], i64 16
+; CHECK-NEXT: [[A4_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[CORO_STATE]], i64 20
; CHECK-NEXT: call void @usePointer(ptr [[CORO_STATE]])
; CHECK-NEXT: call void @usePointer(ptr [[A1_RELOAD_ADDR]])
; CHECK-NEXT: call void @usePointer(ptr [[CORO_STATE]])
>From e97e60e9f6dfce4216c25457e81866551feb39ca Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash at gmail.com>
Date: Fri, 13 Feb 2026 18:57:34 +0000
Subject: [PATCH 2/2] update remaining tests by hand
---
.../Coroutines/coro-alloca-outside-frame.ll | 5 ++--
llvm/test/Transforms/Coroutines/coro-async.ll | 4 +--
.../Coroutines/coro-debug-coro-frame.ll | 28 ++++++++++---------
.../Transforms/Coroutines/coro-materialize.ll | 13 +++++----
.../coro-split-dbg-nested-struct.ll | 2 --
.../Coroutines/coro-split-sink-lifetime-01.ll | 4 +--
.../Coroutines/coro-split-sink-lifetime-02.ll | 4 ++-
.../Coroutines/coro-split-tbaa-md.ll | 6 ++--
8 files changed, 36 insertions(+), 30 deletions(-)
diff --git a/llvm/test/Transforms/Coroutines/coro-alloca-outside-frame.ll b/llvm/test/Transforms/Coroutines/coro-alloca-outside-frame.ll
index e93e97fb06643..58d1aea739e3f 100644
--- a/llvm/test/Transforms/Coroutines/coro-alloca-outside-frame.ll
+++ b/llvm/test/Transforms/Coroutines/coro-alloca-outside-frame.ll
@@ -38,11 +38,10 @@ suspend:
}
; %y and %alias_phi would all go to the frame, but not %x
-; CHECK: %f.Frame = type { ptr, ptr, i64, ptr, i1 }
; CHECK-LABEL: @f(
; CHECK: %x = alloca i64, align 8, !coro.outside.frame !0
-; CHECK-NOT: %x.reload.addr = getelementptr inbounds %f.Frame, ptr %hdl, i32 0, i32 2
-; CHECK: %y.reload.addr = getelementptr inbounds %f.Frame, ptr %hdl, i32 0, i32 2
+; CHECK-NOT: %x.reload.addr = getelementptr inbounds i8, ptr %hdl, i64 16
+; CHECK: %y.reload.addr = getelementptr inbounds i8, ptr %hdl, i64 16
; CHECK: %alias_phi = phi ptr [ %y.reload.addr, %merge.from.flag_false ], [ %x, %entry ]
declare ptr @llvm.coro.free(token, ptr)
diff --git a/llvm/test/Transforms/Coroutines/coro-async.ll b/llvm/test/Transforms/Coroutines/coro-async.ll
index f94c6c11aa8b1..2c2febde6758f 100644
--- a/llvm/test/Transforms/Coroutines/coro-async.ll
+++ b/llvm/test/Transforms/Coroutines/coro-async.ll
@@ -137,7 +137,7 @@ define void @my_async_function_pa(ptr %ctxt, ptr %task, ptr %actor) {
; CHECK: store ptr %async.ctxt, ptr [[CALLEE_CTXT]]
; Make sure the spill is underaligned to the max context alignment (16).
; CHECK-O0: [[VECTOR_SPILL:%.*]] = load <4 x double>, ptr {{.*}}
-; CHECK-O0: [[VECTOR_SPILL_ADDR:%.*]] = getelementptr inbounds %my_async_function.Frame, ptr {{.*}}, i32 0, i32 1
+; CHECK-O0: [[VECTOR_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr {{.*}}, i64 32
; CHECK-O0: store <4 x double> [[VECTOR_SPILL]], ptr [[VECTOR_SPILL_ADDR]], align 16
; CHECK: tail call swiftcc void @asyncSuspend(ptr nonnull [[CALLEE_CTXT]], ptr %task, ptr %actor)
; CHECK: ret void
@@ -149,7 +149,7 @@ define void @my_async_function_pa(ptr %ctxt, ptr %task, ptr %actor) {
; CHECK: entryresume.0:
; CHECK: [[CALLER_CONTEXT:%.*]] = load ptr, ptr %0
; CHECK: [[FRAME_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 128
-; CHECK-O0: [[VECTOR_SPILL_ADDR:%.*]] = getelementptr inbounds %my_async_function.Frame, ptr {{.*}}, i32 0, i32 1
+; CHECK-O0: [[VECTOR_SPILL_ADDR:%.*]] = getelementptr inbounds i8, ptr {{.*}}, i64 32
; CHECK-O0: load <4 x double>, ptr [[VECTOR_SPILL_ADDR]], align 16
; CHECK: [[CALLEE_CTXT_SPILL_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 160
; CHECK: [[CALLEE_CTXT_RELOAD:%.*]] = load ptr, ptr [[CALLEE_CTXT_SPILL_ADDR]]
diff --git a/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll b/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
index f2aedefcfd381..28f8beddcdb7b 100644
--- a/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
+++ b/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll
@@ -16,51 +16,53 @@
; CHECK-DAG: ![[RAMP:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov",
; CHECK-DAG: ![[CORO_FRAME]] = !DILocalVariable(name: "__coro_frame", scope: ![[RAMP]], file: ![[FILE]], line: [[CORO_FRAME_LINE:[0-9]+]], type: ![[FRAME_TYPE:[0-9]+]], flags: DIFlagArtificial)
; CHECK-DAG: ![[FRAME_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "f.coro_frame_ty", {{.*}}elements: ![[ELEMENTS:[0-9]+]]
-; CHECK-DAG: ![[ELEMENTS]] = !{![[RESUME_FN:[0-9]+]], ![[DESTROY_FN:[0-9]+]], ![[PROMISE:[0-9]+]], ![[VECTOR_TYPE:[0-9]+]], ![[INT64_0:[0-9]+]], ![[DOUBLE_1:[0-9]+]], ![[INT64_PTR:[0-9]+]], ![[INT32_2:[0-9]+]], ![[INT32_3:[0-9]+]], ![[UNALIGNED_UNKNOWN:[0-9]+]], ![[STRUCT:[0-9]+]], ![[CORO_INDEX:[0-9]+]], ![[SMALL_UNKNOWN:[0-9]+]]
+; CHECK-DAG: ![[ELEMENTS]] = !{![[RESUME_FN:[0-9]+]], ![[DESTROY_FN:[0-9]+]], ![[CORO_INDEX:[0-9]+]], ![[INT32_0:[0-9]+]], ![[INT32_1:[0-9]+]], ![[INT64_2:[0-9]+]], ![[DOUBLE_3:[0-9]+]], ![[INT64_PTR_4:[0-9]+]], ![[STRUCT_5:[0-9]+]], ![[VECTOR_TYPE_6:[0-9]+]], ![[SMALL_UNKNOWN_7:[0-9]+]], ![[UNALIGNED_UNKNOWN_8:[0-9]+]], ![[PROMISE:[0-9]+]]
; CHECK-DAG: ![[RESUME_FN]] = !DIDerivedType(tag: DW_TAG_member, name: "__resume_fn"{{.*}}, baseType: ![[RESUME_FN_TYPE:[0-9]+]]{{.*}}, flags: DIFlagArtificial
; CHECK-DAG: ![[RESUME_FN_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
; CHECK-DAG: ![[DESTROY_FN]] = !DIDerivedType(tag: DW_TAG_member, name: "__destroy_fn"{{.*}}, baseType: ![[RESUME_FN_TYPE]]{{.*}}, flags: DIFlagArtificial
; CHECK-DAG: ![[PROMISE]] = !DIDerivedType(tag: DW_TAG_member, name: "__promise",{{.*}}baseType: ![[PROMISE_BASE:[0-9]+]]
; CHECK-DAG: ![[PROMISE_BASE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "promise_type"
-; CHECK-DAG: ![[VECTOR_TYPE]] = !DIDerivedType(tag: DW_TAG_member, name: "_0",{{.*}}baseType: ![[VECTOR_TYPE_BASE:[0-9]+]], size: 128
+; CHECK-DAG: ![[VECTOR_TYPE_6]] = !DIDerivedType(tag: DW_TAG_member, name: "_6",{{.*}}baseType: ![[VECTOR_TYPE_BASE:[0-9]+]], size: 128
; CHECK-DAG: ![[VECTOR_TYPE_BASE]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[UNKNOWN_TYPE_BASE:[0-9]+]], size: 128, align: 16, elements: ![[VECTOR_TYPE_BASE_ELEMENTS:[0-9]+]])
; CHECK-DAG: ![[UNKNOWN_TYPE_BASE]] = !DIBasicType(name: "UnknownType", size: 8, encoding: DW_ATE_unsigned_char, flags: DIFlagArtificial)
; CHECK-DAG: ![[VECTOR_TYPE_BASE_ELEMENTS]] = !{![[VECTOR_TYPE_BASE_SUBRANGE:[0-9]+]]}
; CHECK-DAG: ![[VECTOR_TYPE_BASE_SUBRANGE]] = !DISubrange(count: 16, lowerBound: 0)
-; CHECK-DAG: ![[INT64_0]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_64_1", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[I64_BASE:[0-9]+]],{{.*}}, flags: DIFlagArtificial
+; CHECK-DAG: ![[INT64_2]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_64_2", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[I64_BASE:[0-9]+]],{{.*}}, flags: DIFlagArtificial
; CHECK-DAG: ![[I64_BASE]] = !DIBasicType(name: "__int_64", size: 64, encoding: DW_ATE_signed, flags: DIFlagArtificial)
-; CHECK-DAG: ![[DOUBLE_1]] = !DIDerivedType(tag: DW_TAG_member, name: "__double__2", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[DOUBLE_BASE:[0-9]+]]{{.*}}, flags: DIFlagArtificial
+; CHECK-DAG: ![[DOUBLE_3]] = !DIDerivedType(tag: DW_TAG_member, name: "__double__3", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[DOUBLE_BASE:[0-9]+]]{{.*}}, flags: DIFlagArtificial
; CHECK-DAG: ![[DOUBLE_BASE]] = !DIBasicType(name: "__double_", size: 64, encoding: DW_ATE_float, flags: DIFlagArtificial)
-; CHECK-DAG: ![[INT32_2]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_32_4", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[I32_BASE:[0-9]+]]{{.*}}, flags: DIFlagArtificial
+; CHECK-DAG: ![[INT32_0]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_32_0", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[I32_BASE:[0-9]+]]{{.*}}, flags: DIFlagArtificial
; CHECK-DAG: ![[I32_BASE]] = !DIBasicType(name: "__int_32", size: 32, encoding: DW_ATE_signed, flags: DIFlagArtificial)
-; CHECK-DAG: ![[INT32_3]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_32_5", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[I32_BASE]]
-; CHECK-DAG: ![[UNALIGNED_UNKNOWN]] = !DIDerivedType(tag: DW_TAG_member, name: "_6",{{.*}}baseType: ![[UNALIGNED_UNKNOWN_BASE:[0-9]+]], size: 9
+; CHECK-DAG: ![[INT32_1]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_32_1", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[I32_BASE]]
+; CHECK-DAG: ![[UNALIGNED_UNKNOWN_8]] = !DIDerivedType(tag: DW_TAG_member, name: "_8",{{.*}}baseType: ![[UNALIGNED_UNKNOWN_BASE:[0-9]+]], size: 16
; CHECK-DAG: ![[UNALIGNED_UNKNOWN_BASE]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[UNKNOWN_TYPE_BASE]], size: 16,{{.*}} elements: ![[UNALIGNED_UNKNOWN_ELEMENTS:[0-9]+]])
; CHECK-DAG: ![[UNALIGNED_UNKNOWN_ELEMENTS]] = !{![[UNALIGNED_UNKNOWN_SUBRANGE:[0-9]+]]}
; CHECK-DAG: ![[UNALIGNED_UNKNOWN_SUBRANGE]] = !DISubrange(count: 2, lowerBound: 0)
-; CHECK-DAG: ![[STRUCT]] = !DIDerivedType(tag: DW_TAG_member, name: "struct_big_structure_7", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[STRUCT_BASE:[0-9]+]]
+; CHECK-DAG: ![[STRUCT_5]] = !DIDerivedType(tag: DW_TAG_member, name: "struct_big_structure_5", scope: ![[FRAME_TYPE]], file: ![[FILE]], line: [[CORO_FRAME_LINE]], baseType: ![[STRUCT_BASE:[0-9]+]]
; CHECK-DAG: ![[STRUCT_BASE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "struct_big_structure"{{.*}}, align: 64, flags: DIFlagArtificial, elements: ![[STRUCT_ELEMENTS:[0-9]+]]
; CHECK-DAG: ![[STRUCT_ELEMENTS]] = !{![[MEM_TYPE:[0-9]+]]}
; CHECK-DAG: ![[MEM_TYPE]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[MEM_TYPE_BASE:[0-9]+]], size: 4000
; CHECK-DAG: ![[MEM_TYPE_BASE]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[UNKNOWN_TYPE_BASE]], size: 4000,
; CHECK-DAG: ![[CORO_INDEX]] = !DIDerivedType(tag: DW_TAG_member, name: "__coro_index"
-; CHECK-DAG: ![[SMALL_UNKNOWN]] = !DIDerivedType(tag: DW_TAG_member, name: "UnknownType_8",{{.*}} baseType: ![[UNKNOWN_TYPE_BASE]], size: 5
+; CHECK-DAG: ![[SMALL_UNKNOWN_7]] = !DIDerivedType(tag: DW_TAG_member, name: "UnknownType_7",{{.*}} baseType: ![[UNKNOWN_TYPE_BASE]], size: 8
; CHECK-DAG: ![[PROMISE_VAR:[0-9]+]] = !DILocalVariable(name: "__promise", scope: ![[RAMP_SCOPE:[0-9]+]], file: ![[FILE]]
; CHECK-DAG: ![[RAMP_SCOPE]] = distinct !DILexicalBlock(scope: ![[RAMP]], file: ![[FILE]], line: 23
; CHECK-DAG: ![[BAR_FUNC:[0-9]+]] = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv",
; CHECK-DAG: ![[BAR_SCOPE:[0-9]+]] = distinct !DILexicalBlock(scope: ![[BAR_FUNC]], file: !1
; CHECK-DAG: ![[FRAME_TYPE_IN_BAR:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "bar.coro_frame_ty", file: ![[FILE]], line: [[BAR_LINE:[0-9]+]]{{.*}}elements: ![[ELEMENTS_IN_BAR:[0-9]+]]
-; CHECK-DAG: ![[ELEMENTS_IN_BAR]] = !{![[RESUME_FN_IN_BAR:[0-9]+]], ![[DESTROY_FN_IN_BAR:[0-9]+]], ![[PROMISE_IN_BAR:[0-9]+]], ![[VECTOR_TYPE_IN_BAR:[0-9]+]], ![[INT64_IN_BAR:[0-9]+]], ![[DOUBLE_IN_BAR:[0-9]+]], ![[INT64_PTR_IN_BAR:[0-9]+]], ![[INT32_IN_BAR:[0-9]+]], ![[STRUCT_IN_BAR:[0-9]+]], ![[CORO_INDEX_IN_BAR:[0-9]+]]
+; CHECK-DAG: ![[ELEMENTS_IN_BAR]] = !{![[RESUME_FN_IN_BAR:[0-9]+]], ![[DESTROY_FN_IN_BAR:[0-9]+]], ![[CORO_INDEX_IN_BAR:[0-9]+]], ![[INT32_IN_BAR:[0-9]+]], ![[INT64_IN_BAR:[0-9]+]], ![[DOUBLE_IN_BAR:[0-9]+]], ![[INT64_PTR_IN_BAR:[0-9]+]], ![[STRUCT_IN_BAR:[0-9]+]], ![[VECTOR_TYPE_IN_BAR:[0-9]+]], ![[PROMISE_IN_BAR:[0-9]+]]
; CHECK-DAG: ![[PROMISE_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "__promise",{{.*}}baseType: ![[PROMISE_BASE]]
-; CHECK-DAG: ![[VECTOR_TYPE_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "_0", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[VECTOR_TYPE_BASE]]
+; CHECK-DAG: ![[VECTOR_TYPE_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "_5", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[VECTOR_TYPE_BASE]]
; CHECK-DAG: ![[INT64_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_64_1", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[I64_BASE]]
; CHECK-DAG: ![[DOUBLE_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "__double__2", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[DOUBLE_BASE]]
-; CHECK-DAG: ![[INT32_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_32_4", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[I32_BASE]]
-; CHECK-DAG: ![[STRUCT_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "struct_big_structure_5", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[STRUCT_BASE_IN_BAR:[0-9]+]]
+; CHECK-DAG: ![[INT32_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "__int_32_0", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[I32_BASE]]
+; CHECK-DAG: ![[STRUCT_IN_BAR]] = !DIDerivedType(tag: DW_TAG_member, name: "struct_big_structure_4", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]], baseType: ![[STRUCT_BASE_IN_BAR:[0-9]+]]
; CHECK-DAG: ![[STRUCT_BASE_IN_BAR]] = !DICompositeType(tag: DW_TAG_structure_type, name: "struct_big_structure", scope: ![[FRAME_TYPE_IN_BAR]], file: ![[FILE]], line: [[BAR_LINE]],{{.*}}, align: 64
; CHECK-DAG: ![[CORO_FRAME_IN_RESUME]] = !DILocalVariable(name: "__coro_frame",{{.*}}type: ![[FRAME_TYPE]]
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
%promise_type = type { i32, i32, double }
%struct.big_structure = type { [500 x i8] }
declare void @produce(ptr)
diff --git a/llvm/test/Transforms/Coroutines/coro-materialize.ll b/llvm/test/Transforms/Coroutines/coro-materialize.ll
index f55db35edb3ea..abe8c61117c6d 100644
--- a/llvm/test/Transforms/Coroutines/coro-materialize.ll
+++ b/llvm/test/Transforms/Coroutines/coro-materialize.ll
@@ -2,17 +2,20 @@
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
; See that we only spilled one value for f
-; CHECK: %f.Frame = type { ptr, ptr, i32, i1 }
-; CHECK: %f_optnone.Frame = type { ptr, ptr, i32, i32, i1 }
; Check other variants where different levels of materialization are achieved
-; CHECK: %f_multiple_remat.Frame = type { ptr, ptr, i32, i1 }
-; CHECK: %f_common_def.Frame = type { ptr, ptr, i32, i1 }
-; CHECK: %f_common_def_multi_result.Frame = type { ptr, ptr, i32, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
; CHECK-LABEL: @f(
+; CHECK: malloc(i32 24)
; CHECK-LABEL: @f_optnone
+; CHECK: malloc(i32 32)
; CHECK-LABEL: @f_multiple_remat(
+; CHECK: malloc(i32 24)
; CHECK-LABEL: @f_common_def(
+; CHECK: malloc(i32 24)
; CHECK-LABEL: @f_common_def_multi_result(
+; CHECK: malloc(i32 24)
define ptr @f(i32 %n) presplitcoroutine {
entry:
diff --git a/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll b/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll
index 0d0ea4991146d..12dfa16991326 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-dbg-nested-struct.ll
@@ -2,8 +2,6 @@
; Test that nested structs in coroutine frames have correct debug info scoping.
-target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
-
; Minimal nested struct types that used to trigger a scoping issue:
; we used to set the wrong `scope` for the `DIDerivedType` member entries of the `DICompositeType`
; as well as the `scope` for `DICompositeType` for the inner struct itself.
diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
index 848cf8b3e461f..8fcfcd49caa7d 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-01.ll
@@ -2,8 +2,8 @@
; sink them to the places after the suspend block.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s
-; CHECK: %a.Frame = type { ptr, ptr, i1 }
-; CHECK: %a_optnone.Frame = type { ptr, ptr, i32, i1 }
+
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
%"struct.std::coroutine_handle" = type { ptr }
%"struct.std::coroutine_handle.0" = type { %"struct.std::coroutine_handle" }
diff --git a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
index 26037043a26ed..c5a69a584d496 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-sink-lifetime-02.ll
@@ -2,6 +2,8 @@
; sink them to the places after the suspend block.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
%"struct.std::coroutine_handle" = type { ptr }
%"struct.std::coroutine_handle.0" = type { %"struct.std::coroutine_handle" }
%"struct.lean_future<int>::Awaiter" = type { i32, %"struct.std::coroutine_handle.0" }
@@ -53,7 +55,7 @@ exit:
}
; CHECK-LABEL: @a.resume(
-; CHECK: %[[VAL:testval.+]] = getelementptr inbounds %a.Frame
+; CHECK: %[[VAL:testval.+]] = getelementptr inbounds i8
; CHECK-NOT: call void @llvm.lifetime.start.p0(ptr %{{.*}})
; CHECK: %test = load i32, ptr %[[VAL]]
diff --git a/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll b/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
index 54a721b1365d8..ec4c4c42769b0 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-tbaa-md.ll
@@ -2,6 +2,8 @@
; Tests that coro-split pass generates TBAA metadata on coroutine frame slot reloads.
; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
+target datalayout = "e-m:e-p:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
define ptr @f(ptr %p) presplitcoroutine {
entry:
%x = load i32, ptr %p, !tbaa !3
@@ -83,7 +85,7 @@ declare void @free(ptr) willreturn allockind("free") "alloc-family"="malloc"
; CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(24) [[HDL:%.*]]) {
; CHECK-NEXT: [[ENTRY_RESUME:.*:]]
; CHECK-NEXT: [[X_RELOAD_ADDR:%.*]] = getelementptr inbounds i8, ptr [[HDL]], i64 16
-; CHECK-NEXT: [[X_RELOAD:%.*]] = load i32, ptr [[X_RELOAD_ADDR]], align 4, !tbaa [[F.FRAME_SLOT_TBAA4:![0-9]+]]
+; CHECK-NEXT: [[X_RELOAD:%.*]] = load i32, ptr [[X_RELOAD_ADDR]], align 4, !tbaa [[F_FRAME_SLOT_TBAA4:![0-9]+]]
; CHECK-NEXT: call void @print(i32 [[X_RELOAD]])
; CHECK-NEXT: call void @free(ptr [[HDL]])
; CHECK-NEXT: ret void
@@ -106,6 +108,6 @@ declare void @free(ptr) willreturn allockind("free") "alloc-family"="malloc"
; CHECK: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}
; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
; CHECK: [[META3]] = !{!"Simple C++ TBAA"}
-; CHECK: [[F.FRAME_SLOT_TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
+; CHECK: [[F_FRAME_SLOT_TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
; CHECK: [[META5]] = !{!"f.Frame Slot", [[META3]], i64 0}
;.
More information about the llvm-commits
mailing list