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(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(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(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 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 Fields; DenseMap FieldIndexByKey; + IntegerType *SwitchIndexType = nullptr; + public: FrameTypeBuilder(LLVMContext &Context, const DataLayout &DL, std::optional 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(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(const_cast(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 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 Elements; DataLayout Layout = F.getDataLayout(); DenseMap DIVarCache; cacheDIVar(FrameData, DIVarCache); - unsigned ResumeIndex = coro::Shape::SwitchFieldIndex::Resume; - unsigned DestroyIndex = coro::Shape::SwitchFieldIndex::Destroy; - unsigned IndexIndex = Shape.SwitchLowering.IndexField; - - DenseMap 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 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> 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 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 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(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(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 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 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(Orig)) { - if (ConstantInt *CI = dyn_cast(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(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 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( - 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 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::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-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-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-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-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-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-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),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),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),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),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-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-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-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::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 010c6b87b3c21..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 @@ -69,12 +71,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,7 +84,7 @@ 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_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]]) 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]])