diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 5ee5fc3aed9686..498b1246292eb4 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -4592,6 +4592,48 @@ struct AAPointerInfo : public AbstractAttribute { /// See AbstractAttribute::getIdAddr() const char *getIdAddr() const override { return &ID; } + /// Helper to represent an access offset and size, with logic to deal with + /// uncertainty and check for overlapping accesses. + struct OffsetAndSize : public std::pair { + using BaseTy = std::pair; + OffsetAndSize(int64_t Offset, int64_t Size) : BaseTy(Offset, Size) {} + OffsetAndSize(const BaseTy &P) : BaseTy(P) {} + int64_t getOffset() const { return first; } + int64_t getSize() const { return second; } + static OffsetAndSize getUnknown() { + return OffsetAndSize(Unknown, Unknown); + } + + /// Return true if offset or size are unknown. + bool offsetOrSizeAreUnknown() const { + return getOffset() == OffsetAndSize::Unknown || + getSize() == OffsetAndSize::Unknown; + } + + /// Return true if this offset and size pair might describe an address that + /// overlaps with \p OAS. + bool mayOverlap(const OffsetAndSize &OAS) const { + // Any unknown value and we are giving up -> overlap. + if (offsetOrSizeAreUnknown() || OAS.offsetOrSizeAreUnknown()) + return true; + + // Check if one offset point is in the other interval [offset, + // offset+size]. + return OAS.getOffset() + OAS.getSize() > getOffset() && + OAS.getOffset() < getOffset() + getSize(); + } + + /// Constant used to represent unknown offset or sizes. + static constexpr int64_t Unknown = 1 << 31; + }; + + /// Call \p CB on all accesses that might interfere with \p OAS and return + /// true if all such accesses were known and the callback returned true for + /// all of them, false otherwise. An access interferes with an offset-size + /// pair if it might read or write that memory region. + virtual bool forallInterferingAccesses( + OffsetAndSize OAS, function_ref CB) const = 0; + /// Call \p CB on all accesses that might interfere with \p LI and return true /// if all such accesses were known and the callback returned true for all of /// them, false otherwise. diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributes.def b/llvm/lib/Target/AMDGPU/AMDGPUAttributes.def new file mode 100644 index 00000000000000..fb9e17fb63e67c --- /dev/null +++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributes.def @@ -0,0 +1,29 @@ +//===--- AMDGPUAttributes.def ---------------------------------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains descriptions of the various function attributes +// that indicate *absence* of the corresponding implicit kernel +// arguments. +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +AMDGPU_ATTRIBUTE(DISPATCH_PTR, "amdgpu-no-dispatch-ptr") +AMDGPU_ATTRIBUTE(QUEUE_PTR, "amdgpu-no-queue-ptr") +AMDGPU_ATTRIBUTE(DISPATCH_ID, "amdgpu-no-dispatch-id") +AMDGPU_ATTRIBUTE(IMPLICIT_ARG_PTR, "amdgpu-no-implicitarg-ptr") +AMDGPU_ATTRIBUTE(HOSTCALL_PTR, "amdgpu-no-hostcall-ptr") +AMDGPU_ATTRIBUTE(WORKGROUP_ID_X, "amdgpu-no-workgroup-id-x") +AMDGPU_ATTRIBUTE(WORKGROUP_ID_Y, "amdgpu-no-workgroup-id-y") +AMDGPU_ATTRIBUTE(WORKGROUP_ID_Z, "amdgpu-no-workgroup-id-z") +AMDGPU_ATTRIBUTE(WORKITEM_ID_X, "amdgpu-no-workitem-id-x") +AMDGPU_ATTRIBUTE(WORKITEM_ID_Y, "amdgpu-no-workitem-id-y") +AMDGPU_ATTRIBUTE(WORKITEM_ID_Z, "amdgpu-no-workitem-id-z") + +#undef AMDGPU_ATTRIBUTE diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp index 284e49b55ed626..f404e2eecedb5d 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp @@ -12,6 +12,7 @@ #include "AMDGPU.h" #include "GCNSubtarget.h" +#include "Utils/AMDGPUBaseInfo.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsR600.h" @@ -22,37 +23,25 @@ using namespace llvm; +#define AMDGPU_ATTRIBUTE(Name, Str) Name##_POS, + +enum ImplicitArgumentPositions { + #include "AMDGPUAttributes.def" + LAST_ARG_POS +}; + +#define AMDGPU_ATTRIBUTE(Name, Str) Name = 1 << Name##_POS, + enum ImplicitArgumentMask { NOT_IMPLICIT_INPUT = 0, - - // SGPRs - DISPATCH_PTR = 1 << 0, - QUEUE_PTR = 1 << 1, - DISPATCH_ID = 1 << 2, - IMPLICIT_ARG_PTR = 1 << 3, - WORKGROUP_ID_X = 1 << 4, - WORKGROUP_ID_Y = 1 << 5, - WORKGROUP_ID_Z = 1 << 6, - - // VGPRS: - WORKITEM_ID_X = 1 << 7, - WORKITEM_ID_Y = 1 << 8, - WORKITEM_ID_Z = 1 << 9, - ALL_ARGUMENT_MASK = (1 << 10) - 1 + #include "AMDGPUAttributes.def" + ALL_ARGUMENT_MASK = (1 << LAST_ARG_POS) - 1 }; +#define AMDGPU_ATTRIBUTE(Name, Str) {Name, Str}, static constexpr std::pair ImplicitAttrs[] = { - {DISPATCH_PTR, "amdgpu-no-dispatch-ptr"}, - {QUEUE_PTR, "amdgpu-no-queue-ptr"}, - {DISPATCH_ID, "amdgpu-no-dispatch-id"}, - {IMPLICIT_ARG_PTR, "amdgpu-no-implicitarg-ptr"}, - {WORKGROUP_ID_X, "amdgpu-no-workgroup-id-x"}, - {WORKGROUP_ID_Y, "amdgpu-no-workgroup-id-y"}, - {WORKGROUP_ID_Z, "amdgpu-no-workgroup-id-z"}, - {WORKITEM_ID_X, "amdgpu-no-workitem-id-x"}, - {WORKITEM_ID_Y, "amdgpu-no-workitem-id-y"}, - {WORKITEM_ID_Z, "amdgpu-no-workitem-id-z"} + #include "AMDGPUAttributes.def" }; // We do not need to note the x workitem or workgroup id because they are always @@ -90,7 +79,7 @@ intrinsicToAttrMask(Intrinsic::ID ID, bool &NonKernelOnly, bool &IsQueuePtr) { case Intrinsic::amdgcn_queue_ptr: case Intrinsic::amdgcn_is_shared: case Intrinsic::amdgcn_is_private: - // TODO: Does not require queue ptr on gfx9+ + // TODO: Does not require the queue pointer on gfx9+ case Intrinsic::trap: case Intrinsic::debugtrap: IsQueuePtr = true; @@ -112,6 +101,17 @@ static bool isDSAddress(const Constant *C) { return AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::REGION_ADDRESS; } +/// Returns true if the function requires the implicit argument be passed +/// regardless of the function contents. +static bool funcRequiresHostcallPtr(const Function &F) { + // Sanitizers require the hostcall buffer passed in the implicit arguments. + return F.hasFnAttribute(Attribute::SanitizeAddress) || + F.hasFnAttribute(Attribute::SanitizeThread) || + F.hasFnAttribute(Attribute::SanitizeMemory) || + F.hasFnAttribute(Attribute::SanitizeHWAddress) || + F.hasFnAttribute(Attribute::SanitizeMemTag); +} + class AMDGPUInformationCache : public InformationCache { public: AMDGPUInformationCache(const Module &M, AnalysisGetter &AG, @@ -129,7 +129,7 @@ class AMDGPUInformationCache : public InformationCache { } private: - /// Check if the ConstantExpr \p CE requires queue ptr attribute. + /// Check if the ConstantExpr \p CE requires the queue pointer. static bool visitConstExpr(const ConstantExpr *CE) { if (CE->getOpcode() == Instruction::AddrSpaceCast) { unsigned SrcAS = CE->getOperand(0)->getType()->getPointerAddressSpace(); @@ -163,7 +163,7 @@ class AMDGPUInformationCache : public InformationCache { } public: - /// Returns true if \p Fn needs a queue ptr attribute because of \p C. + /// Returns true if \p Fn needs the queue pointer because of \p C. bool needsQueuePtr(const Constant *C, Function &Fn) { bool IsNonEntryFunc = !AMDGPU::isEntryFunctionCC(Fn.getCallingConv()); bool HasAperture = hasApertureRegs(Fn); @@ -182,7 +182,7 @@ class AMDGPUInformationCache : public InformationCache { } private: - /// Used to determine if the Constant needs a queue ptr attribute. + /// Used to determine if the Constant needs the queue pointer. DenseMap ConstantStatus; }; @@ -327,7 +327,20 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { void initialize(Attributor &A) override { Function *F = getAssociatedFunction(); + + // If the function requires the implicit arg pointer due to sanitizers, + // assume it's needed even if explicitly marked as not requiring it. + const bool NeedsHostcall = funcRequiresHostcallPtr(*F); + if (NeedsHostcall) { + removeAssumedBits(IMPLICIT_ARG_PTR); + removeAssumedBits(HOSTCALL_PTR); + } + for (auto Attr : ImplicitAttrs) { + if (NeedsHostcall && + (Attr.first == IMPLICIT_ARG_PTR || Attr.first == HOSTCALL_PTR)) + continue; + if (F->hasFnAttribute(Attr.second)) addKnownBits(Attr.first); } @@ -355,7 +368,6 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { return indicatePessimisticFixpoint(); bool IsNonEntryFunc = !AMDGPU::isEntryFunctionCC(F->getCallingConv()); - auto &InfoCache = static_cast(A.getInfoCache()); bool NeedsQueuePtr = false; @@ -377,13 +389,58 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { } } - // If we found that we need amdgpu-queue-ptr, nothing else to do. + if (!NeedsQueuePtr) { + NeedsQueuePtr = checkForQueuePtr(A); + } + if (NeedsQueuePtr) { removeAssumedBits(QUEUE_PTR); - return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED : - ChangeStatus::UNCHANGED; } + if (funcRetrievesHostcallPtr(A)) { + removeAssumedBits(IMPLICIT_ARG_PTR); + removeAssumedBits(HOSTCALL_PTR); + } + + return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED + : ChangeStatus::UNCHANGED; + } + + ChangeStatus manifest(Attributor &A) override { + SmallVector AttrList; + LLVMContext &Ctx = getAssociatedFunction()->getContext(); + + for (auto Attr : ImplicitAttrs) { + if (isKnown(Attr.first)) + AttrList.push_back(Attribute::get(Ctx, Attr.second)); + } + + return IRAttributeManifest::manifestAttrs(A, getIRPosition(), AttrList, + /* ForceReplace */ true); + } + + const std::string getAsStr() const override { + std::string Str; + raw_string_ostream OS(Str); + OS << "AMDInfo["; + for (auto Attr : ImplicitAttrs) + OS << ' ' << Attr.second; + OS << " ]"; + return OS.str(); + } + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() const override {} + +private: + bool checkForQueuePtr(Attributor &A) { + Function *F = getAssociatedFunction(); + bool IsNonEntryFunc = !AMDGPU::isEntryFunctionCC(F->getCallingConv()); + + auto &InfoCache = static_cast(A.getInfoCache()); + + bool NeedsQueuePtr = false; + auto CheckAddrSpaceCasts = [&](Instruction &I) { unsigned SrcAS = static_cast(I).getSrcAddressSpace(); if (castRequiresQueuePtr(SrcAS)) { @@ -398,7 +455,7 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { // `checkForAllInstructions` is much more cheaper than going through all // instructions, try it first. - // amdgpu-queue-ptr is not needed if aperture regs is present. + // The queue pointer is not needed if aperture regs is present. if (!HasApertureRegs) { bool UsedAssumedInformation = false; A.checkForAllInstructions(CheckAddrSpaceCasts, *this, @@ -406,61 +463,55 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { UsedAssumedInformation); } - // If we found that we need amdgpu-queue-ptr, nothing else to do. - if (NeedsQueuePtr) { - removeAssumedBits(QUEUE_PTR); - return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED : - ChangeStatus::UNCHANGED; - } + // If we found that we need the queue pointer, nothing else to do. + if (NeedsQueuePtr) + return true; - if (!IsNonEntryFunc && HasApertureRegs) { - return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED : - ChangeStatus::UNCHANGED; - } + if (!IsNonEntryFunc && HasApertureRegs) + return false; for (BasicBlock &BB : *F) { for (Instruction &I : BB) { for (const Use &U : I.operands()) { if (const auto *C = dyn_cast(U)) { - if (InfoCache.needsQueuePtr(C, *F)) { - removeAssumedBits(QUEUE_PTR); - return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED : - ChangeStatus::UNCHANGED; - } + if (InfoCache.needsQueuePtr(C, *F)) + return true; } } } } - return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED : - ChangeStatus::UNCHANGED; + return false; } - ChangeStatus manifest(Attributor &A) override { - SmallVector AttrList; - LLVMContext &Ctx = getAssociatedFunction()->getContext(); - - for (auto Attr : ImplicitAttrs) { - if (isKnown(Attr.first)) - AttrList.push_back(Attribute::get(Ctx, Attr.second)); - } + bool funcRetrievesHostcallPtr(Attributor &A) { + auto Pos = llvm::AMDGPU::getHostcallImplicitArgPosition(); + + // Check if this is a call to the implicitarg_ptr builtin and it + // is used to retrieve the hostcall pointer. The implicit arg for + // hostcall is not used only if every use of the implicitarg_ptr + // is a load that clearly does not retrieve any byte of the + // hostcall pointer. We check this by tracing all the uses of the + // initial call to the implicitarg_ptr intrinsic. + auto DoesNotLeadToHostcallPtr = [&](Instruction &I) { + auto &Call = cast(I); + if (Call.getIntrinsicID() != Intrinsic::amdgcn_implicitarg_ptr) + return true; + + const auto &PointerInfoAA = A.getAAFor( + *this, IRPosition::callsite_returned(Call), DepClassTy::REQUIRED); + + AAPointerInfo::OffsetAndSize OAS(Pos, 8); + return PointerInfoAA.forallInterferingAccesses( + OAS, [](const AAPointerInfo::Access &Acc, bool IsExact) { + return Acc.getRemoteInst()->isDroppable(); + }); + }; - return IRAttributeManifest::manifestAttrs(A, getIRPosition(), AttrList, - /* ForceReplace */ true); + bool UsedAssumedInformation = false; + return !A.checkForAllCallLikeInstructions(DoesNotLeadToHostcallPtr, *this, + UsedAssumedInformation); } - - const std::string getAsStr() const override { - std::string Str; - raw_string_ostream OS(Str); - OS << "AMDInfo["; - for (auto Attr : ImplicitAttrs) - OS << ' ' << Attr.second; - OS << " ]"; - return OS.str(); - } - - /// See AbstractAttribute::trackStatistics() - void trackStatistics() const override {} }; AAAMDAttributes &AAAMDAttributes::createForPosition(const IRPosition &IRP, @@ -497,7 +548,8 @@ class AMDGPUAttributor : public ModulePass { BumpPtrAllocator Allocator; AMDGPUInformationCache InfoCache(M, AG, Allocator, nullptr, *TM); DenseSet Allowed( - {&AAAMDAttributes::ID, &AAUniformWorkGroupSize::ID, &AACallEdges::ID}); + {&AAAMDAttributes::ID, &AAUniformWorkGroupSize::ID, + &AACallEdges::ID, &AAPointerInfo::ID}); Attributor A(Functions, InfoCache, CGUpdater, &Allowed); diff --git a/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp b/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp index 3b4f92f613e77f..a3e1f08e3aa06c 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp @@ -405,7 +405,7 @@ void MetadataStreamerV2::emitHiddenKernelArgs(const Function &Func) { if (HiddenArgNumBytes >= 32) { if (Func.getParent()->getNamedMetadata("llvm.printf.fmts")) emitKernelArg(DL, Int8PtrTy, Align(8), ValueKind::HiddenPrintfBuffer); - else if (Func.getParent()->getFunction("__ockl_hostcall_internal")) { + else if (!Func.hasFnAttribute("amdgpu-no-hostcall-ptr")) { // The printf runtime binding pass should have ensured that hostcall and // printf are not used in the same module. assert(!Func.getParent()->getNamedMetadata("llvm.printf.fmts")); @@ -821,7 +821,7 @@ void MetadataStreamerV3::emitHiddenKernelArgs(const Function &Func, if (M->getNamedMetadata("llvm.printf.fmts")) emitKernelArg(DL, Int8PtrTy, Align(8), "hidden_printf_buffer", Offset, Args); - else if (M->getModuleFlag("amdgpu_hostcall")) { + else if (!Func.hasFnAttribute("amdgpu-no-hostcall-ptr")) { // The printf runtime binding pass should have ensured that hostcall and // printf are not used in the same module. assert(!M->getNamedMetadata("llvm.printf.fmts")); diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp index 9da7b9f5145deb..b1473f21d6f083 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -127,6 +127,22 @@ bool isHsaAbiVersion3Or4(const MCSubtargetInfo *STI) { return isHsaAbiVersion3(STI) || isHsaAbiVersion4(STI); } +// FIXME: All such magic numbers about the ABI should be in a +// central TD file. +unsigned getHostcallImplicitArgPosition() { + switch (AmdhsaCodeObjectVersion) { + case 2: + case 3: + case 4: + return 24; + case 5: + return 80; + default: + llvm_unreachable("Unexpected code object version"); + return 0; + } +} + #define GET_MIMGBaseOpcodesTable_IMPL #define GET_MIMGDimInfoTable_IMPL #define GET_MIMGInfoTable_IMPL diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h index aaf06125cdddb9..0a21f909f05e47 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -51,6 +51,9 @@ bool isHsaAbiVersion4(const MCSubtargetInfo *STI); /// false otherwise. bool isHsaAbiVersion3Or4(const MCSubtargetInfo *STI); +/// \returns The offset of the hostcall pointer argument from implicitarg_ptr +unsigned getHostcallImplicitArgPosition(); + struct GcnBufferFormatInfo { unsigned Format; unsigned BitsPerComp; diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index cdfc7fe0d6572f..4c76633be4979d 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -759,9 +759,6 @@ namespace llvm { namespace AA { namespace PointerInfo { -/// An access kind description as used by AAPointerInfo. -struct OffsetAndSize; - struct State; } // namespace PointerInfo @@ -779,7 +776,7 @@ struct DenseMapInfo : DenseMapInfo { /// Helper that allows OffsetAndSize as a key in a DenseMap. template <> -struct DenseMapInfo +struct DenseMapInfo : DenseMapInfo> {}; /// Helper for AA::PointerInfo::Acccess DenseMap/Set usage ignoring everythign @@ -795,35 +792,6 @@ struct AccessAsInstructionInfo : DenseMapInfo { } // namespace llvm -/// Helper to represent an access offset and size, with logic to deal with -/// uncertainty and check for overlapping accesses. -struct AA::PointerInfo::OffsetAndSize : public std::pair { - using BaseTy = std::pair; - OffsetAndSize(int64_t Offset, int64_t Size) : BaseTy(Offset, Size) {} - OffsetAndSize(const BaseTy &P) : BaseTy(P) {} - int64_t getOffset() const { return first; } - int64_t getSize() const { return second; } - static OffsetAndSize getUnknown() { return OffsetAndSize(Unknown, Unknown); } - - /// Return true if this offset and size pair might describe an address that - /// overlaps with \p OAS. - bool mayOverlap(const OffsetAndSize &OAS) const { - // Any unknown value and we are giving up -> overlap. - if (OAS.getOffset() == OffsetAndSize::Unknown || - OAS.getSize() == OffsetAndSize::Unknown || - getOffset() == OffsetAndSize::Unknown || - getSize() == OffsetAndSize::Unknown) - return true; - - // Check if one offset point is in the other interval [offset, offset+size]. - return OAS.getOffset() + OAS.getSize() > getOffset() && - OAS.getOffset() < getOffset() + getSize(); - } - - /// Constant used to represent unknown offset or sizes. - static constexpr int64_t Unknown = 1 << 31; -}; - /// Implementation of the DenseMapInfo. /// ///{ @@ -957,14 +925,14 @@ struct AA::PointerInfo::State : public AbstractState { using Accesses = DenseSet; /// We store all accesses in bins denoted by their offset and size. - using AccessBinsTy = DenseMap; + using AccessBinsTy = DenseMap; AccessBinsTy::const_iterator begin() const { return AccessBins.begin(); } AccessBinsTy::const_iterator end() const { return AccessBins.end(); } protected: /// The bins with all the accesses for the associated pointer. - DenseMap AccessBins; + DenseMap AccessBins; /// Add a new access to the state at offset \p Offset and with size \p Size. /// The access is associated with \p I, writes \p Content (if anything), and @@ -975,7 +943,7 @@ struct AA::PointerInfo::State : public AbstractState { AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI = nullptr, Accesses *BinPtr = nullptr) { - OffsetAndSize Key{Offset, Size}; + AAPointerInfo::OffsetAndSize Key{Offset, Size}; Accesses &Bin = BinPtr ? *BinPtr : AccessBins[Key]; AAPointerInfo::Access Acc(&I, RemoteI ? RemoteI : &I, Content, Kind, Ty); // Check if we have an access for this instruction in this bin, if not, @@ -992,14 +960,34 @@ struct AA::PointerInfo::State : public AbstractState { return *It == Before ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED; } + /// See AAPointerInfo::forallInterferingAccesses. + bool forallInterferingAccesses( + AAPointerInfo::OffsetAndSize OAS, + function_ref CB) const { + if (!isValidState()) + return false; + + for (auto &It : AccessBins) { + AAPointerInfo::OffsetAndSize ItOAS = It.getFirst(); + if (!OAS.mayOverlap(ItOAS)) + continue; + bool IsExact = OAS == ItOAS && !OAS.offsetOrSizeAreUnknown(); + for (auto &Access : It.getSecond()) + if (!CB(Access, IsExact)) + return false; + } + return true; + } + /// See AAPointerInfo::forallInterferingAccesses. bool forallInterferingAccesses( Instruction &I, function_ref CB) const { if (!isValidState()) return false; + // First find the offset and size of I. - OffsetAndSize OAS(-1, -1); + AAPointerInfo::OffsetAndSize OAS(-1, -1); for (auto &It : AccessBins) { for (auto &Access : It.getSecond()) { if (Access.getRemoteInst() == &I) { @@ -1010,20 +998,13 @@ struct AA::PointerInfo::State : public AbstractState { if (OAS.getSize() != -1) break; } + // No access for I was found, we are done. if (OAS.getSize() == -1) return true; // Now that we have an offset and size, find all overlapping ones and use // the callback on the accesses. - for (auto &It : AccessBins) { - OffsetAndSize ItOAS = It.getFirst(); - if (!OAS.mayOverlap(ItOAS)) - continue; - for (auto &Access : It.getSecond()) - if (!CB(Access, OAS == ItOAS)) - return false; - } - return true; + return forallInterferingAccesses(OAS, CB); } private: @@ -1052,6 +1033,12 @@ struct AAPointerInfoImpl return AAPointerInfo::manifest(A); } + bool forallInterferingAccesses( + OffsetAndSize OAS, + function_ref CB) + const override { + return State::forallInterferingAccesses(OAS, CB); + } bool forallInterferingAccesses( LoadInst &LI, function_ref CB) const override { @@ -1115,7 +1102,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl { bool handleAccess(Attributor &A, Instruction &I, Value &Ptr, Optional Content, AccessKind Kind, int64_t Offset, ChangeStatus &Changed, Type *Ty, - int64_t Size = AA::PointerInfo::OffsetAndSize::Unknown) { + int64_t Size = OffsetAndSize::Unknown) { using namespace AA::PointerInfo; // No need to find a size if one is given or the offset is unknown. if (Offset != OffsetAndSize::Unknown && Size == OffsetAndSize::Unknown && @@ -1131,7 +1118,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl { /// Helper struct, will support ranges eventually. struct OffsetInfo { - int64_t Offset = AA::PointerInfo::OffsetAndSize::Unknown; + int64_t Offset = OffsetAndSize::Unknown; bool operator==(const OffsetInfo &OI) const { return Offset == OI.Offset; } }; diff --git a/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp b/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp index fdc914a72bfd7f..8cd16ca3906f1a 100644 --- a/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp +++ b/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp @@ -63,9 +63,6 @@ static Value *callPrintfBegin(IRBuilder<> &Builder, Value *Version) { auto Int64Ty = Builder.getInt64Ty(); auto M = Builder.GetInsertBlock()->getModule(); auto Fn = M->getOrInsertFunction("__ockl_printf_begin", Int64Ty, Int64Ty); - if (!M->getModuleFlag("amdgpu_hostcall")) { - M->addModuleFlag(llvm::Module::Override, "amdgpu_hostcall", 1); - } return Builder.CreateCall(Fn, Version); } diff --git a/llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll b/llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll index 668b2f9ed506b7..0850b8c7744317 100644 --- a/llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll +++ b/llvm/test/CodeGen/AMDGPU/addrspacecast-constantexpr.ll @@ -230,6 +230,6 @@ attributes #1 = { nounwind } ; AKF_HSA: attributes #[[ATTR1]] = { nounwind } ;. ; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree nounwind willreturn } -; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll index a9266323686338..c32713e9baf1db 100644 --- a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll +++ b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll @@ -837,7 +837,7 @@ define float @func_other_intrinsic_call(float %arg) #3 { ret float %fadd } -; Implicit arguments need to be enabled for sanitizers +; Hostcall needs to be enabled for sanitizers define amdgpu_kernel void @kern_sanitize_address() #4 { ; AKF_HSA-LABEL: define {{[^@]+}}@kern_sanitize_address ; AKF_HSA-SAME: () #[[ATTR5:[0-9]+]] { @@ -853,7 +853,7 @@ define amdgpu_kernel void @kern_sanitize_address() #4 { ret void } -; Implicit arguments need to be enabled for sanitizers +; Hostcall needs to be enabled for sanitizers define void @func_sanitize_address() #4 { ; AKF_HSA-LABEL: define {{[^@]+}}@func_sanitize_address ; AKF_HSA-SAME: () #[[ATTR5]] { @@ -869,7 +869,7 @@ define void @func_sanitize_address() #4 { ret void } -; Implicit arguments need to be enabled for sanitizers +; Hostcall needs to be enabled for sanitizers define void @func_indirect_sanitize_address() #3 { ; AKF_HSA-LABEL: define {{[^@]+}}@func_indirect_sanitize_address ; AKF_HSA-SAME: () #[[ATTR3]] { @@ -877,7 +877,7 @@ define void @func_indirect_sanitize_address() #3 { ; AKF_HSA-NEXT: ret void ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@func_indirect_sanitize_address -; ATTRIBUTOR_HSA-SAME: () #[[ATTR16]] { +; ATTRIBUTOR_HSA-SAME: () #[[ATTR18:[0-9]+]] { ; ATTRIBUTOR_HSA-NEXT: call void @func_sanitize_address() ; ATTRIBUTOR_HSA-NEXT: ret void ; @@ -885,7 +885,7 @@ define void @func_indirect_sanitize_address() #3 { ret void } -; Implicit arguments need to be enabled for sanitizers +; Hostcall needs to be enabled for sanitizers define amdgpu_kernel void @kern_indirect_sanitize_address() #3 { ; AKF_HSA-LABEL: define {{[^@]+}}@kern_indirect_sanitize_address ; AKF_HSA-SAME: () #[[ATTR4]] { @@ -893,7 +893,7 @@ define amdgpu_kernel void @kern_indirect_sanitize_address() #3 { ; AKF_HSA-NEXT: ret void ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@kern_indirect_sanitize_address -; ATTRIBUTOR_HSA-SAME: () #[[ATTR16]] { +; ATTRIBUTOR_HSA-SAME: () #[[ATTR18]] { ; ATTRIBUTOR_HSA-NEXT: call void @func_sanitize_address() ; ATTRIBUTOR_HSA-NEXT: ret void ; @@ -912,7 +912,7 @@ define amdgpu_kernel void @kern_decl_sanitize_address() #3 { ; AKF_HSA-NEXT: ret void ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@kern_decl_sanitize_address -; ATTRIBUTOR_HSA-SAME: () #[[ATTR19:[0-9]+]] { +; ATTRIBUTOR_HSA-SAME: () #[[ATTR15]] { ; ATTRIBUTOR_HSA-NEXT: call void @extern_func_sanitize_address() ; ATTRIBUTOR_HSA-NEXT: ret void ; @@ -937,24 +937,24 @@ attributes #5 = { nounwind sanitize_address "amdgpu-no-implicitarg-ptr" } ; AKF_HSA: attributes #[[ATTR6:[0-9]+]] = { nounwind sanitize_address "amdgpu-no-implicitarg-ptr" } ;. ; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } -; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR4]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR5]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR6]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR7]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR8]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR9]] = { nounwind "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR10]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR11]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR12]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="gfx900" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR13]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="gfx900" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR14]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR4]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR5]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR6]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR7]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR8]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR9]] = { nounwind "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR10]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR11]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR12]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="gfx900" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR13]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="gfx900" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR14]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "target-cpu"="fiji" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR15]] = { nounwind "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR16]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR17]] = { nounwind sanitize_address "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR18:[0-9]+]] = { nounwind sanitize_address "amdgpu-no-implicitarg-ptr" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR19]] = { nounwind "amdgpu-no-implicitarg-ptr" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR16]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR17]] = { nounwind sanitize_address "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR18]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR19:[0-9]+]] = { nounwind sanitize_address "amdgpu-no-implicitarg-ptr" "uniform-work-group-size"="false" } ; ATTRIBUTOR_HSA: attributes #[[ATTR20]] = { nounwind } ;. diff --git a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll index 6b0ea17abd4100..52dff4e2627aa3 100644 --- a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll +++ b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll @@ -647,15 +647,15 @@ attributes #1 = { nounwind } ; AKF_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-stack-objects" } ;. ; ATTRIBUTOR_HSA: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } -; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR4]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR5]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR6]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR7]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR8]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR9]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR10]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_HSA: attributes #[[ATTR11]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR4]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR5]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR6]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR7]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR8]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR9]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR10]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_HSA: attributes #[[ATTR11]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll index c93a6a4f797dea..31230b47baeb5b 100644 --- a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll +++ b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features.ll @@ -418,13 +418,13 @@ attributes #1 = { nounwind } ; AKF_CHECK: attributes #[[ATTR1]] = { nounwind } ;. ; ATTRIBUTOR_CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind readnone speculatable willreturn } -; ATTRIBUTOR_CHECK: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR4]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR5]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR6]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR7]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR8]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } -; ATTRIBUTOR_CHECK: attributes #[[ATTR9]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR1]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR2]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR3]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR4]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR5]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR6]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR7]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR8]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } +; ATTRIBUTOR_CHECK: attributes #[[ATTR9]] = { nounwind "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workitem-id-x" "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/direct-indirect-call.ll b/llvm/test/CodeGen/AMDGPU/direct-indirect-call.ll index da8fdb8acdce5b..6c6850030faf69 100644 --- a/llvm/test/CodeGen/AMDGPU/direct-indirect-call.ll +++ b/llvm/test/CodeGen/AMDGPU/direct-indirect-call.ll @@ -35,6 +35,6 @@ define amdgpu_kernel void @test_direct_indirect_call() { ret void } ;. -; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; CHECK: attributes #[[ATTR1]] = { "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/duplicate-attribute-indirect.ll b/llvm/test/CodeGen/AMDGPU/duplicate-attribute-indirect.ll index c19dc86afb7bc5..c68d4362554d24 100644 --- a/llvm/test/CodeGen/AMDGPU/duplicate-attribute-indirect.ll +++ b/llvm/test/CodeGen/AMDGPU/duplicate-attribute-indirect.ll @@ -42,6 +42,6 @@ attributes #0 = { "amdgpu-no-dispatch-id" } ;. ; AKF_GCN: attributes #[[ATTR0]] = { "amdgpu-calls" "amdgpu-no-dispatch-id" "amdgpu-stack-objects" } ;. -; ATTRIBUTOR_GCN: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_GCN: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_GCN: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/hsa-metadata-enqueue-kernel.ll b/llvm/test/CodeGen/AMDGPU/hsa-metadata-enqueue-kernel.ll index eb49add8705c2b..0c394b6cd13bc1 100644 --- a/llvm/test/CodeGen/AMDGPU/hsa-metadata-enqueue-kernel.ll +++ b/llvm/test/CodeGen/AMDGPU/hsa-metadata-enqueue-kernel.ll @@ -26,6 +26,9 @@ ; CHECK-NEXT: - Size: 8 ; CHECK-NEXT: Align: 8 ; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ +; CHECK-NEXT: - Size: 8 +; CHECK-NEXT: Align: 8 +; CHECK-NEXT: ValueKind: HiddenNone ; CHECK-NOT: ValueKind: HiddenDefaultQueue ; CHECK-NOT: ValueKind: HiddenCompletionAction define amdgpu_kernel void @test_non_enqueue_kernel_caller(i8 %a) #0 diff --git a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-absent-v3.ll b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-absent-v3.ll deleted file mode 100644 index a1cee23387a89f..00000000000000 --- a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-absent-v3.ll +++ /dev/null @@ -1,51 +0,0 @@ -; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 -filetype=obj -o - < %s | llvm-readelf --notes - | FileCheck %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 -amdgpu-dump-hsa-metadata -amdgpu-verify-hsa-metadata -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s - -; CHECK: --- -; CHECK: amdhsa.kernels: -; CHECK: - .args: -; CHECK-NEXT: - .name: a -; CHECK-NEXT: .offset: 0 -; CHECK-NEXT: .size: 1 -; CHECK-NEXT: .type_name: char -; CHECK-NEXT: .value_kind: by_value -; CHECK-NEXT: - .offset: 8 -; CHECK-NEXT: .size: 8 -; CHECK-NEXT: .value_kind: hidden_global_offset_x -; CHECK-NEXT: - .offset: 16 -; CHECK-NEXT: .size: 8 -; CHECK-NEXT: .value_kind: hidden_global_offset_y -; CHECK-NEXT: - .offset: 24 -; CHECK-NEXT: .size: 8 -; CHECK-NEXT: .value_kind: hidden_global_offset_z - -; CHECK-NOT: .value_kind: hidden_hostcall_buffer - -; CHECK: .language: OpenCL C -; CHECK-NEXT: .language_version: -; CHECK-NEXT: - 2 -; CHECK-NEXT: - 0 -; CHECK: .name: test_kernel -; CHECK: .symbol: test_kernel.kd - -define amdgpu_kernel void @test_kernel(i8 %a) #0 - !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 - !kernel_arg_base_type !3 !kernel_arg_type_qual !4 { - ret void -} - -; CHECK: amdhsa.version: -; CHECK-NEXT: - 1 -; CHECK-NEXT: - 0 - -attributes #0 = { "amdgpu-implicitarg-num-bytes"="48" } - -!1 = !{i32 0} -!2 = !{!"none"} -!3 = !{!"char"} -!4 = !{!""} - -!opencl.ocl.version = !{!90} -!90 = !{i32 2, i32 0} - -; PARSER: AMDGPU HSA Metadata Parser Test: PASS diff --git a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-absent.ll b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-absent.ll deleted file mode 100644 index 702f32d4f98ca6..00000000000000 --- a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-absent.ll +++ /dev/null @@ -1,48 +0,0 @@ -; RUN: llc -mtriple=amdgcn-amd-amdhsa --amdhsa-code-object-version=2 -mcpu=gfx900 -filetype=obj -o - < %s | llvm-readelf --notes - | FileCheck %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa --amdhsa-code-object-version=2 -mcpu=gfx900 -amdgpu-dump-hsa-metadata -amdgpu-verify-hsa-metadata -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s - -; CHECK: --- -; CHECK: Version: [ 1, 0 ] -; CHECK: Kernels: - -; CHECK: - Name: test_kernel -; CHECK-NEXT: SymbolName: 'test_kernel@kd' -; CHECK-NEXT: Language: OpenCL C -; CHECK-NEXT: LanguageVersion: [ 2, 0 ] -; CHECK-NEXT: Args: -; CHECK-NEXT: - Name: a -; CHECK-NEXT: TypeName: char -; CHECK-NEXT: Size: 1 -; CHECK-NEXT: Align: 1 -; CHECK-NEXT: ValueKind: ByValue -; CHECK-NEXT: AccQual: Default -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ -; CHECK-NOT: ValueKind: HiddenHostcallBuffer -; CHECK-NOT: ValueKind: HiddenDefaultQueue -; CHECK-NOT: ValueKind: HiddenCompletionAction - -define amdgpu_kernel void @test_kernel(i8 %a) #0 - !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 - !kernel_arg_base_type !3 !kernel_arg_type_qual !4 { - ret void -} - -attributes #0 = { "amdgpu-implicitarg-num-bytes"="48" } - -!1 = !{i32 0} -!2 = !{!"none"} -!3 = !{!"char"} -!4 = !{!""} - -!opencl.ocl.version = !{!90} -!90 = !{i32 2, i32 0} - -; PARSER: AMDGPU HSA Metadata Parser Test: PASS diff --git a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present-v3.ll b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present-v3-asan.ll similarity index 87% rename from llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present-v3.ll rename to llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present-v3-asan.ll index 15186b389c8b63..8ae5948d995011 100644 --- a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present-v3.ll +++ b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present-v3-asan.ll @@ -1,5 +1,5 @@ ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 -filetype=obj -o - < %s | llvm-readelf --notes - | FileCheck %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 -amdgpu-dump-hsa-metadata -amdgpu-verify-hsa-metadata -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 -amdgpu-dump-hsa-metadata -amdgpu-verify-hsa-metadata -filetype=obj -o - < %s 2>&1 | FileCheck %s ; CHECK: --- ; CHECK: amdhsa.kernels: @@ -39,7 +39,7 @@ define amdgpu_kernel void @test_kernel(i8 %a) #0 ; CHECK-NEXT: - 1 ; CHECK-NEXT: - 0 -attributes #0 = { "amdgpu-implicitarg-num-bytes"="48" } +attributes #0 = { sanitize_address "amdgpu-implicitarg-num-bytes"="48" } !1 = !{i32 0} !2 = !{!"none"} @@ -48,8 +48,3 @@ attributes #0 = { "amdgpu-implicitarg-num-bytes"="48" } !opencl.ocl.version = !{!90} !90 = !{i32 2, i32 0} - -!llvm.module.flags = !{!0} -!0 = !{i32 1, !"amdgpu_hostcall", i32 1} - -; PARSER: AMDGPU HSA Metadata Parser Test: PASS diff --git a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present.ll b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present.ll deleted file mode 100644 index c79285338468cd..00000000000000 --- a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-present.ll +++ /dev/null @@ -1,53 +0,0 @@ -; RUN: llc -mtriple=amdgcn-amd-amdhsa --amdhsa-code-object-version=2 -mcpu=gfx900 -filetype=obj -o - < %s | llvm-readelf --notes - | FileCheck %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa --amdhsa-code-object-version=2 -mcpu=gfx900 -amdgpu-dump-hsa-metadata -amdgpu-verify-hsa-metadata -filetype=obj -o - < %s 2>&1 | FileCheck --check-prefix=PARSER %s - -; CHECK: --- -; CHECK: Version: [ 1, 0 ] -; CHECK: Kernels: - -; CHECK: - Name: test_kernel -; CHECK-NEXT: SymbolName: 'test_kernel@kd' -; CHECK-NEXT: Language: OpenCL C -; CHECK-NEXT: LanguageVersion: [ 2, 0 ] -; CHECK-NEXT: Args: -; CHECK-NEXT: - Name: a -; CHECK-NEXT: TypeName: char -; CHECK-NEXT: Size: 1 -; CHECK-NEXT: Align: 1 -; CHECK-NEXT: ValueKind: ByValue -; CHECK-NEXT: AccQual: Default -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenGlobalOffsetX -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenGlobalOffsetY -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenGlobalOffsetZ -; CHECK-NEXT: - Size: 8 -; CHECK-NEXT: Align: 8 -; CHECK-NEXT: ValueKind: HiddenHostcallBuffer -; CHECK-NEXT: AddrSpaceQual: Global -; CHECK-NOT: ValueKind: HiddenDefaultQueue -; CHECK-NOT: ValueKind: HiddenCompletionAction - -declare <2 x i64> @__ockl_hostcall_internal(i8*, i32, i64, i64, i64, i64, i64, i64, i64, i64) - -define amdgpu_kernel void @test_kernel(i8 %a) #0 - !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 - !kernel_arg_base_type !3 !kernel_arg_type_qual !4 { - ret void -} - -attributes #0 = { "amdgpu-implicitarg-num-bytes"="48" } - -!1 = !{i32 0} -!2 = !{!"none"} -!3 = !{!"char"} -!4 = !{!""} - -!opencl.ocl.version = !{!90} -!90 = !{i32 2, i32 0} - -; PARSER: AMDGPU HSA Metadata Parser Test: PASS diff --git a/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-v3.ll b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-v3.ll new file mode 100644 index 00000000000000..734ad53e9be0d4 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/hsa-metadata-hostcall-v3.ll @@ -0,0 +1,303 @@ +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 -filetype=obj -o - < %s | llvm-readelf --notes - | FileCheck %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 --amdhsa-code-object-version=3 < %s | FileCheck --check-prefix=CHECK %s + +declare void @function1() + +declare void @function2() #0 + +; Function Attrs: noinline +define void @function3(i8 addrspace(4)* %argptr, i8 addrspace(4)* addrspace(1)* %sink) #4 { + store i8 addrspace(4)* %argptr, i8 addrspace(4)* addrspace(1)* %sink, align 8 + ret void +} + +; Function Attrs: noinline +define void @function4(i64 %arg, i64* %a) #4 { + store i64 %arg, i64* %a + ret void +} + +; Function Attrs: noinline +define void @function5(i8 addrspace(4)* %ptr, i64* %sink) #4 { + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 8 + %cast = bitcast i8 addrspace(4)* %gep to i64 addrspace(4)* + %x = load i64, i64 addrspace(4)* %cast + store i64 %x, i64* %sink + ret void +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare align 4 i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() #1 + +; CHECK: amdhsa.kernels: +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel10 +define amdgpu_kernel void @test_kernel10(i8* %a) #2 { + store i8 3, i8* %a, align 1 + ret void +} + +; Call to an extern function + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel20 +define amdgpu_kernel void @test_kernel20(i8* %a) #2 { + call void @function1() + store i8 3, i8* %a, align 1 + ret void +} + +; Explicit attribute on kernel + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel21 +define amdgpu_kernel void @test_kernel21(i8* %a) #3 { + call void @function1() + store i8 3, i8* %a, align 1 + ret void +} + +; Explicit attribute on extern callee + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel22 +define amdgpu_kernel void @test_kernel22(i8* %a) #2 { + call void @function2() + store i8 3, i8* %a, align 1 + ret void +} + +; Access more bytes than the pointer size + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel30 +define amdgpu_kernel void @test_kernel30(i128* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 16 + %cast = bitcast i8 addrspace(4)* %gep to i128 addrspace(4)* + %x = load i128, i128 addrspace(4)* %cast + store i128 %x, i128* %a + ret void +} + +; Typical load of hostcall buffer pointer + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel40 +define amdgpu_kernel void @test_kernel40(i64* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 24 + %cast = bitcast i8 addrspace(4)* %gep to i64 addrspace(4)* + %x = load i64, i64 addrspace(4)* %cast + store i64 %x, i64* %a + ret void +} + +; Typical usage, overriden by explicit attribute on kernel + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel41 +define amdgpu_kernel void @test_kernel41(i64* %a) #3 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 24 + %cast = bitcast i8 addrspace(4)* %gep to i64 addrspace(4)* + %x = load i64, i64 addrspace(4)* %cast + store i64 %x, i64* %a + ret void +} + +; Access to implicit arg before the hostcall pointer + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel42 +define amdgpu_kernel void @test_kernel42(i64* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 16 + %cast = bitcast i8 addrspace(4)* %gep to i64 addrspace(4)* + %x = load i64, i64 addrspace(4)* %cast + store i64 %x, i64* %a + ret void +} + +; Access to implicit arg after the hostcall pointer + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel43 +define amdgpu_kernel void @test_kernel43(i64* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 32 + %cast = bitcast i8 addrspace(4)* %gep to i64 addrspace(4)* + %x = load i64, i64 addrspace(4)* %cast + store i64 %x, i64* %a + ret void +} + +; Accessing a byte just before the hostcall pointer + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel44 +define amdgpu_kernel void @test_kernel44(i8* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 23 + %x = load i8, i8 addrspace(4)* %gep, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Accessing a byte inside the hostcall pointer + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel45 +define amdgpu_kernel void @test_kernel45(i8* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 24 + %x = load i8, i8 addrspace(4)* %gep, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Accessing a byte inside the hostcall pointer + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel46 +define amdgpu_kernel void @test_kernel46(i8* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 31 + %x = load i8, i8 addrspace(4)* %gep, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Accessing a byte just after the hostcall pointer + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel47 +define amdgpu_kernel void @test_kernel47(i8* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 32 + %x = load i8, i8 addrspace(4)* %gep, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Access with an unknown offset + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel50 +define amdgpu_kernel void @test_kernel50(i8* %a, i32 %b) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i32 %b + %x = load i8, i8 addrspace(4)* %gep, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Multiple geps reaching the hostcall pointer argument. + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel51 +define amdgpu_kernel void @test_kernel51(i8* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep1 = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 16 + %gep2 = getelementptr inbounds i8, i8 addrspace(4)* %gep1, i64 8 + %x = load i8, i8 addrspace(4)* %gep2, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Multiple geps not reaching the hostcall pointer argument. + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel52 +define amdgpu_kernel void @test_kernel52(i8* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep1 = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 16 + %gep2 = getelementptr inbounds i8, i8 addrspace(4)* %gep1, i64 16 + %x = load i8, i8 addrspace(4)* %gep2, align 1 + store i8 %x, i8* %a, align 1 + ret void +} + +; Hostcall pointer used inside a function call + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel60 +define amdgpu_kernel void @test_kernel60(i64* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 24 + %cast = bitcast i8 addrspace(4)* %gep to i64 addrspace(4)* + %x = load i64, i64 addrspace(4)* %cast + call void @function4(i64 %x, i64* %a) + ret void +} + +; Hostcall pointer retrieved inside a function call; chain of geps + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel61 +define amdgpu_kernel void @test_kernel61(i64* %a) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i64 16 + call void @function5(i8 addrspace(4)* %gep, i64* %a) + ret void +} + +; Pointer captured + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel70 +define amdgpu_kernel void @test_kernel70(i8 addrspace(4)* addrspace(1)* %sink) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i32 42 + store i8 addrspace(4)* %gep, i8 addrspace(4)* addrspace(1)* %sink, align 8 + ret void +} + +; Pointer captured inside function call + +; CHECK: - .args: +; CHECK: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel71 +define amdgpu_kernel void @test_kernel71(i8 addrspace(4)* addrspace(1)* %sink) #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i32 42 + call void @function3(i8 addrspace(4)* %gep, i8 addrspace(4)* addrspace(1)* %sink) + ret void +} + +; Ineffective pointer capture + +; CHECK: - .args: +; CHECK-NOT: hidden_hostcall_buffer +; CHECK-LABEL: .name: test_kernel72 +define amdgpu_kernel void @test_kernel72() #2 { + %ptr = tail call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() + %gep = getelementptr inbounds i8, i8 addrspace(4)* %ptr, i32 42 + store i8 addrspace(4)* %gep, i8 addrspace(4)* addrspace(1)* undef, align 8 + ret void +} + +attributes #0 = { "amdgpu-no-hostcall-ptr" } +attributes #1 = { nounwind readnone speculatable willreturn } +attributes #2 = { "amdgpu-implicitarg-num-bytes"="48" } +attributes #3 = { "amdgpu-implicitarg-num-bytes"="48" "amdgpu-no-hostcall-ptr" } +attributes #4 = { noinline } diff --git a/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll b/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll index f4eaa608237627..3786e8ef2ad405 100644 --- a/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll +++ b/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll @@ -73,6 +73,6 @@ define amdgpu_kernel void @test_simple_indirect_call() { ;. ; AKF_GCN: attributes #[[ATTR0]] = { "amdgpu-calls" "amdgpu-stack-objects" } ;. -; ATTRIBUTOR_GCN: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; ATTRIBUTOR_GCN: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ; ATTRIBUTOR_GCN: attributes #[[ATTR1]] = { "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/uniform-work-group-attribute-missing.ll b/llvm/test/CodeGen/AMDGPU/uniform-work-group-attribute-missing.ll index 003d4c74c0fc9a..78caeeaa1f3de4 100644 --- a/llvm/test/CodeGen/AMDGPU/uniform-work-group-attribute-missing.ll +++ b/llvm/test/CodeGen/AMDGPU/uniform-work-group-attribute-missing.ll @@ -31,5 +31,5 @@ define amdgpu_kernel void @kernel1() #1 { attributes #0 = { "uniform-work-group-size"="true" } ;. -; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/uniform-work-group-multistep.ll b/llvm/test/CodeGen/AMDGPU/uniform-work-group-multistep.ll index e9179b0213b9c5..afb0d07f0c256b 100644 --- a/llvm/test/CodeGen/AMDGPU/uniform-work-group-multistep.ll +++ b/llvm/test/CodeGen/AMDGPU/uniform-work-group-multistep.ll @@ -97,6 +97,6 @@ define amdgpu_kernel void @kernel2() #0 { attributes #0 = { "uniform-work-group-size"="true" } ;. -; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; CHECK: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } +; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/uniform-work-group-nested-function-calls.ll b/llvm/test/CodeGen/AMDGPU/uniform-work-group-nested-function-calls.ll index 292022039e5d69..2dc57b42cfbaa5 100644 --- a/llvm/test/CodeGen/AMDGPU/uniform-work-group-nested-function-calls.ll +++ b/llvm/test/CodeGen/AMDGPU/uniform-work-group-nested-function-calls.ll @@ -41,6 +41,6 @@ define amdgpu_kernel void @kernel3() #2 { attributes #2 = { "uniform-work-group-size"="true" } ;. -; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; CHECK: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } +; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/uniform-work-group-prevent-attribute-propagation.ll b/llvm/test/CodeGen/AMDGPU/uniform-work-group-prevent-attribute-propagation.ll index cd888064cada2c..745928d7846772 100644 --- a/llvm/test/CodeGen/AMDGPU/uniform-work-group-prevent-attribute-propagation.ll +++ b/llvm/test/CodeGen/AMDGPU/uniform-work-group-prevent-attribute-propagation.ll @@ -41,6 +41,6 @@ define amdgpu_kernel void @kernel2() #2 { attributes #1 = { "uniform-work-group-size"="true" } ;. -; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; CHECK: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } +; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR1]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll b/llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll index 3ac9f0675bfeff..7a5f1eae341f8f 100644 --- a/llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll +++ b/llvm/test/CodeGen/AMDGPU/uniform-work-group-recursion-test.ll @@ -101,7 +101,7 @@ define amdgpu_kernel void @kernel(i32 addrspace(1)* %m) #1 { attributes #0 = { nounwind readnone } attributes #1 = { "uniform-work-group-size"="true" } ;. -; CHECK: attributes #[[ATTR0]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } -; CHECK: attributes #[[ATTR1]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } -; CHECK: attributes #[[ATTR2]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } +; CHECK: attributes #[[ATTR0]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR1]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } +; CHECK: attributes #[[ATTR2]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } ;. diff --git a/llvm/test/CodeGen/AMDGPU/uniform-work-group-test.ll b/llvm/test/CodeGen/AMDGPU/uniform-work-group-test.ll index 1381f871369d26..bdc1c28f1654d4 100644 --- a/llvm/test/CodeGen/AMDGPU/uniform-work-group-test.ll +++ b/llvm/test/CodeGen/AMDGPU/uniform-work-group-test.ll @@ -61,5 +61,5 @@ define amdgpu_kernel void @kernel3() #0 { attributes #0 = { "uniform-work-group-size"="false" } ;. -; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } +; CHECK: attributes #[[ATTR0]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } ;.