diff options
| author | Mingming Liu <mingmingl@google.com> | 2025-09-10 15:25:31 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-10 15:25:31 -0700 |
| commit | 1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch) | |
| tree | 57f4b1f313c8cf74eed8819870f39c36ea263c68 /llvm/lib/IR | |
| parent | 898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff) | |
| parent | b8cefcb601ddaa18482555c4ff363c01a270c2fe (diff) | |
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'llvm/lib/IR')
| -rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/IR/Assumptions.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/IR/Attributes.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 114 | ||||
| -rw-r--r-- | llvm/lib/IR/DataLayout.cpp | 53 | ||||
| -rw-r--r-- | llvm/lib/IR/DebugInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/IR/DebugLoc.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/IR/Module.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/IR/ProfDataUtils.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/IR/RuntimeLibcalls.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/IR/Type.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/IR/Value.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/IR/Verifier.cpp | 73 |
13 files changed, 280 insertions, 62 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index dc6d599fa958..094678f32af2 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -88,6 +88,8 @@ using namespace llvm; +// See https://llvm.org/docs/DebuggingLLVM.html for why these flags are useful. + static cl::opt<bool> PrintInstAddrs("print-inst-addrs", cl::Hidden, cl::desc("Print addresses of instructions when dumping")); diff --git a/llvm/lib/IR/Assumptions.cpp b/llvm/lib/IR/Assumptions.cpp index 6adbbc4a63b0..f8bbcb32231c 100644 --- a/llvm/lib/IR/Assumptions.cpp +++ b/llvm/lib/IR/Assumptions.cpp @@ -101,12 +101,16 @@ bool llvm::addAssumptions(CallBase &CB, return ::addAssumptionsImpl(CB, Assumptions); } -StringSet<> llvm::KnownAssumptionStrings({ - "omp_no_openmp", // OpenMP 5.1 - "omp_no_openmp_routines", // OpenMP 5.1 - "omp_no_parallelism", // OpenMP 5.1 - "omp_no_openmp_constructs", // OpenMP 6.0 - "ompx_spmd_amenable", // OpenMPOpt extension - "ompx_no_call_asm", // OpenMPOpt extension - "ompx_aligned_barrier", // OpenMPOpt extension -}); +StringSet<> &llvm::getKnownAssumptionStrings() { + static StringSet<> Object({ + "omp_no_openmp", // OpenMP 5.1 + "omp_no_openmp_routines", // OpenMP 5.1 + "omp_no_parallelism", // OpenMP 5.1 + "omp_no_openmp_constructs", // OpenMP 6.0 + "ompx_spmd_amenable", // OpenMPOpt extension + "ompx_no_call_asm", // OpenMPOpt extension + "ompx_aligned_barrier", // OpenMPOpt extension + }); + + return Object; +} diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index d1fbcb9e893a..4ac2ebd55dca 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -954,6 +954,19 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, return get(C, B); } +AttributeSet AttributeSet::addAttributes(LLVMContext &C, + const AttrBuilder &B) const { + if (!hasAttributes()) + return get(C, B); + + if (!B.hasAttributes()) + return *this; + + AttrBuilder Merged(C, *this); + Merged.merge(B); + return get(C, Merged); +} + AttributeSet AttributeSet::removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const { if (!hasAttribute(Kind)) return *this; diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index e200f3626e69..8d8120ac9ed9 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -48,6 +48,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/NVPTXAddrSpace.h" #include "llvm/Support/Regex.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/TargetParser/Triple.h" #include <cstdint> #include <cstring> @@ -106,6 +107,24 @@ static bool upgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID, return true; } +// Upgrade the declaration of multiply and add bytes intrinsics whose input +// arguments' types have changed from vectors of i32 to vectors of i8 +static bool upgradeX86MultiplyAddBytes(Function *F, Intrinsic::ID IID, + Function *&NewFn) { + // check if input argument type is a vector of i8 + Type *Arg1Type = F->getFunctionType()->getParamType(1); + Type *Arg2Type = F->getFunctionType()->getParamType(2); + if (Arg1Type->isVectorTy() && + cast<VectorType>(Arg1Type)->getElementType()->isIntegerTy(8) && + Arg2Type->isVectorTy() && + cast<VectorType>(Arg2Type)->getElementType()->isIntegerTy(8)) + return false; + + rename(F); + NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), IID); + return true; +} + static bool upgradeX86BF16Intrinsic(Function *F, Intrinsic::ID IID, Function *&NewFn) { if (F->getReturnType()->getScalarType()->isBFloatTy()) @@ -545,19 +564,34 @@ static bool upgradeX86IntrinsicFunction(Function *F, StringRef Name, if (ID != Intrinsic::not_intrinsic) return upgradeX86IntrinsicsWith8BitMask(F, ID, NewFn); - if (Name.consume_front("avx512.mask.cmp.")) { - // Added in 7.0 - ID = StringSwitch<Intrinsic::ID>(Name) - .Case("pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128) - .Case("pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256) - .Case("pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512) - .Case("ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128) - .Case("ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256) - .Case("ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512) - .Default(Intrinsic::not_intrinsic); - if (ID != Intrinsic::not_intrinsic) - return upgradeX86MaskedFPCompare(F, ID, NewFn); - return false; // No other 'x86.avx523.mask.cmp.*'. + if (Name.consume_front("avx512.")) { + if (Name.consume_front("mask.cmp.")) { + // Added in 7.0 + ID = StringSwitch<Intrinsic::ID>(Name) + .Case("pd.128", Intrinsic::x86_avx512_mask_cmp_pd_128) + .Case("pd.256", Intrinsic::x86_avx512_mask_cmp_pd_256) + .Case("pd.512", Intrinsic::x86_avx512_mask_cmp_pd_512) + .Case("ps.128", Intrinsic::x86_avx512_mask_cmp_ps_128) + .Case("ps.256", Intrinsic::x86_avx512_mask_cmp_ps_256) + .Case("ps.512", Intrinsic::x86_avx512_mask_cmp_ps_512) + .Default(Intrinsic::not_intrinsic); + if (ID != Intrinsic::not_intrinsic) + return upgradeX86MaskedFPCompare(F, ID, NewFn); + } else if (Name.starts_with("vpdpbusd.") || + Name.starts_with("vpdpbusds.")) { + // Added in 21.1 + ID = StringSwitch<Intrinsic::ID>(Name) + .Case("vpdpbusd.128", Intrinsic::x86_avx512_vpdpbusd_128) + .Case("vpdpbusd.256", Intrinsic::x86_avx512_vpdpbusd_256) + .Case("vpdpbusd.512", Intrinsic::x86_avx512_vpdpbusd_512) + .Case("vpdpbusds.128", Intrinsic::x86_avx512_vpdpbusds_128) + .Case("vpdpbusds.256", Intrinsic::x86_avx512_vpdpbusds_256) + .Case("vpdpbusds.512", Intrinsic::x86_avx512_vpdpbusds_512) + .Default(Intrinsic::not_intrinsic); + if (ID != Intrinsic::not_intrinsic) + return upgradeX86MultiplyAddBytes(F, ID, NewFn); + } + return false; // No other 'x86.avx512.*'. } if (Name.consume_front("avx512bf16.")) { @@ -4148,6 +4182,32 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2)}; + + // Input arguments types were incorrectly set to vectors of i32 before but + // they should be vectors of i8. Insert bit cast when encountering the old + // types + if (Args[1]->getType()->isVectorTy() && + cast<VectorType>(Args[1]->getType()) + ->getElementType() + ->isIntegerTy(32) && + Args[2]->getType()->isVectorTy() && + cast<VectorType>(Args[2]->getType()) + ->getElementType() + ->isIntegerTy(32)) { + Type *NewArgType = nullptr; + if (VecWidth == 128) + NewArgType = VectorType::get(Builder.getInt8Ty(), 16, false); + else if (VecWidth == 256) + NewArgType = VectorType::get(Builder.getInt8Ty(), 32, false); + else if (VecWidth == 512) + NewArgType = VectorType::get(Builder.getInt8Ty(), 64, false); + else + llvm_unreachable("Unexpected vector bit width"); + + Args[1] = Builder.CreateBitCast(Args[1], NewArgType); + Args[2] = Builder.CreateBitCast(Args[2], NewArgType); + } + Rep = Builder.CreateIntrinsic(IID, Args); Value *PassThru = ZeroMask ? ConstantAggregateZero::get(CI->getType()) : CI->getArgOperand(0); @@ -5155,6 +5215,23 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { CI->eraseFromParent(); return; } + + case Intrinsic::x86_avx512_vpdpbusd_128: + case Intrinsic::x86_avx512_vpdpbusd_256: + case Intrinsic::x86_avx512_vpdpbusd_512: + case Intrinsic::x86_avx512_vpdpbusds_128: + case Intrinsic::x86_avx512_vpdpbusds_256: + case Intrinsic::x86_avx512_vpdpbusds_512: { + unsigned NumElts = CI->getType()->getPrimitiveSizeInBits() / 8; + Value *Args[] = {CI->getArgOperand(0), CI->getArgOperand(1), + CI->getArgOperand(2)}; + Type *NewArgType = VectorType::get(Builder.getInt8Ty(), NumElts, false); + Args[1] = Builder.CreateBitCast(Args[1], NewArgType); + Args[2] = Builder.CreateBitCast(Args[2], NewArgType); + + NewCall = Builder.CreateCall(NewFn, Args); + break; + } } assert(NewCall && "Should have either set this variable or returned through " "the default case"); @@ -5256,6 +5333,7 @@ bool llvm::UpgradeDebugInfo(Module &M) { if (DisableAutoUpgradeDebugInfo) return false; + llvm::TimeTraceScope timeScope("Upgrade debug info"); // We need to get metadata before the module is verified (i.e., getModuleFlag // makes assumptions that we haven't verified yet). Carefully extract the flag // from the metadata. @@ -5381,6 +5459,16 @@ bool static upgradeSingleNVVMAnnotation(GlobalValue *GV, StringRef K, upgradeNVVMFnVectorAttr("nvvm.cluster_dim", K[0], GV, V); return true; } + if (K == "grid_constant") { + const auto Attr = Attribute::get(GV->getContext(), "nvvm.grid_constant"); + for (const auto &Op : cast<MDNode>(V)->operands()) { + // For some reason, the index is 1-based in the metadata. Good thing we're + // able to auto-upgrade it! + const auto Index = mdconst::extract<ConstantInt>(Op)->getZExtValue() - 1; + cast<Function>(GV)->addParamAttr(Index, Attr); + } + return true; + } return false; } diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp index dbd6d81ad2e2..ed629d4e5ea2 100644 --- a/llvm/lib/IR/DataLayout.cpp +++ b/llvm/lib/IR/DataLayout.cpp @@ -187,7 +187,6 @@ const char *DataLayout::getManglingComponent(const Triple &T) { // Default primitive type specifications. // NOTE: These arrays must be sorted by type bit width. constexpr DataLayout::PrimitiveSpec DefaultIntSpecs[] = { - {1, Align::Constant<1>(), Align::Constant<1>()}, // i1:8:8 {8, Align::Constant<1>(), Align::Constant<1>()}, // i8:8:8 {16, Align::Constant<2>(), Align::Constant<2>()}, // i16:16:16 {32, Align::Constant<4>(), Align::Constant<4>()}, // i32:32:32 @@ -694,7 +693,12 @@ void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align DataLayout::getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const { - auto I = lower_bound(IntSpecs, BitWidth, LessPrimitiveBitWidth()); + auto I = IntSpecs.begin(); + for (; I != IntSpecs.end(); ++I) { + if (I->BitWidth >= BitWidth) + break; + } + // If we don't have an exact match, use alignment of next larger integer // type. If there is none, use alignment of largest integer type by going // back one element. @@ -839,6 +843,44 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const { } } +TypeSize DataLayout::getTypeAllocSize(Type *Ty) const { + switch (Ty->getTypeID()) { + case Type::ArrayTyID: { + // The alignment of the array is the alignment of the element, so there + // is no need for further adjustment. + auto *ATy = cast<ArrayType>(Ty); + return ATy->getNumElements() * getTypeAllocSize(ATy->getElementType()); + } + case Type::StructTyID: { + const StructLayout *Layout = getStructLayout(cast<StructType>(Ty)); + TypeSize Size = Layout->getSizeInBytes(); + + if (cast<StructType>(Ty)->isPacked()) + return Size; + + Align A = std::max(StructABIAlignment, Layout->getAlignment()); + return alignTo(Size, A.value()); + } + case Type::IntegerTyID: { + unsigned BitWidth = Ty->getIntegerBitWidth(); + TypeSize Size = TypeSize::getFixed(divideCeil(BitWidth, 8)); + Align A = getIntegerAlignment(BitWidth, /*ABI=*/true); + return alignTo(Size, A.value()); + } + case Type::PointerTyID: { + unsigned AS = Ty->getPointerAddressSpace(); + TypeSize Size = TypeSize::getFixed(getPointerSize(AS)); + return alignTo(Size, getPointerABIAlignment(AS).value()); + } + case Type::TargetExtTyID: { + Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType(); + return getTypeAllocSize(LayoutTy); + } + default: + return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value()); + } +} + Align DataLayout::getABITypeAlign(Type *Ty) const { return getAlignment(Ty, true); } @@ -926,12 +968,13 @@ static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) { return APInt::getZero(BitWidth); } - APInt Index = Offset.sdiv(ElemSize); - Offset -= Index * ElemSize; + uint64_t FixedElemSize = ElemSize.getFixedValue(); + APInt Index = Offset.sdiv(FixedElemSize); + Offset -= Index * FixedElemSize; if (Offset.isNegative()) { // Prefer a positive remaining offset to allow struct indexing. --Index; - Offset += ElemSize; + Offset += FixedElemSize; assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative"); } return Index; diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 8e523bcf7960..166521a27664 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -36,6 +36,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/TimeProfiler.h" #include <algorithm> #include <cassert> #include <optional> @@ -563,6 +564,7 @@ bool llvm::stripDebugInfo(Function &F) { } bool llvm::StripDebugInfo(Module &M) { + llvm::TimeTraceScope timeScope("Strip debug info"); bool Changed = false; for (NamedMDNode &NMD : llvm::make_early_inc_range(M.named_metadata())) { @@ -755,7 +757,7 @@ private: return getReplacementMDNode(N); }; - // Seperate recursive doRemap and operator [] into 2 lines to avoid + // Separate recursive doRemap and operator [] into 2 lines to avoid // out-of-order evaluations since both of them can access the same memory // location in map Replacements. auto Value = doRemap(N); diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp index 79c5b896f8f2..01dafcab94ce 100644 --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -181,10 +181,19 @@ DebugLoc DebugLoc::getMergedLocations(ArrayRef<DebugLoc> Locs) { return Merged; } DebugLoc DebugLoc::getMergedLocation(DebugLoc LocA, DebugLoc LocB) { - if (!LocA) - return LocA; - if (!LocB) + if (!LocA || !LocB) { + // If coverage tracking is enabled, prioritize returning empty non-annotated + // locations to empty annotated locations. +#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE + if (!LocA && LocA.getKind() == DebugLocKind::Normal) + return LocA; + if (!LocB && LocB.getKind() == DebugLocKind::Normal) + return LocB; +#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE + if (!LocA) + return LocA; return LocB; + } return DILocation::getMergedLocation(LocA, LocB); } diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 70d364176062..30b5e48652b2 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -44,6 +44,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/RandomNumberGenerator.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/VersionTuple.h" #include <cassert> #include <cstdint> @@ -478,6 +479,7 @@ Error Module::materializeAll() { } Error Module::materializeMetadata() { + llvm::TimeTraceScope timeScope("Materialize metadata"); if (!Materializer) return Error::success(); return Materializer->materializeMetadata(); diff --git a/llvm/lib/IR/ProfDataUtils.cpp b/llvm/lib/IR/ProfDataUtils.cpp index d24263f8b3bd..b41256f59909 100644 --- a/llvm/lib/IR/ProfDataUtils.cpp +++ b/llvm/lib/IR/ProfDataUtils.cpp @@ -250,7 +250,15 @@ void setExplicitlyUnknownBranchWeights(Instruction &I) { MDB.createString(MDProfLabels::UnknownBranchWeightsMarker))); } -bool isExplicitlyUnknownBranchWeightsMetadata(const MDNode &MD) { +void setExplicitlyUnknownFunctionEntryCount(Function &F) { + MDBuilder MDB(F.getContext()); + F.setMetadata( + LLVMContext::MD_prof, + MDNode::get(F.getContext(), + MDB.createString(MDProfLabels::UnknownBranchWeightsMarker))); +} + +bool isExplicitlyUnknownProfileMetadata(const MDNode &MD) { if (MD.getNumOperands() != 1) return false; return MD.getOperand(0).equalsStr(MDProfLabels::UnknownBranchWeightsMarker); @@ -260,7 +268,7 @@ bool hasExplicitlyUnknownBranchWeights(const Instruction &I) { auto *MD = I.getMetadata(LLVMContext::MD_prof); if (!MD) return false; - return isExplicitlyUnknownBranchWeightsMetadata(*MD); + return isExplicitlyUnknownProfileMetadata(*MD); } void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights, diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 3c324f2fe0d8..4fe5714a74e3 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -40,13 +40,19 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, // hard-float calling convention by default. if (!TT.isWatchABI()) { if (isAAPCS_ABI(TT, ABIName)) { - setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_AAPCS); - setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_AAPCS); - setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_AAPCS); + setLibcallImplCallingConv(RTLIB::impl___truncsfhf2, + CallingConv::ARM_AAPCS); + setLibcallImplCallingConv(RTLIB::impl___truncdfhf2, + CallingConv::ARM_AAPCS); + setLibcallImplCallingConv(RTLIB::impl___extendhfsf2, + CallingConv::ARM_AAPCS); } else { - setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_APCS); - setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_APCS); - setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_APCS); + setLibcallImplCallingConv(RTLIB::impl___truncsfhf2, + CallingConv::ARM_APCS); + setLibcallImplCallingConv(RTLIB::impl___truncdfhf2, + CallingConv::ARM_APCS); + setLibcallImplCallingConv(RTLIB::impl___extendhfsf2, + CallingConv::ARM_APCS); } } diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp index 9c3466234035..9db48e8f6a96 100644 --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -1036,7 +1036,8 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) { // DirectX resources if (Name.starts_with("dx.")) return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::CanBeGlobal, - TargetExtType::CanBeLocal); + TargetExtType::CanBeLocal, + TargetExtType::IsTokenLike); // Opaque types in the AMDGPU name space. if (Name == "amdgcn.named.barrier") { @@ -1054,6 +1055,14 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) { return TargetTypeInfo(Type::getVoidTy(C)); } +bool Type::isTokenLikeTy() const { + if (isTokenTy()) + return true; + if (auto *TT = dyn_cast<TargetExtType>(this)) + return TT->hasProperty(TargetExtType::Property::IsTokenLike); + return false; +} + Type *TargetExtType::getLayoutType() const { return getTargetTypeInfo(this).LayoutType; } diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 5928c89029b8..4e8f359481b8 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -836,6 +836,9 @@ bool Value::canBeFreed() const { return false; } + if (isa<IntToPtrInst>(this) && getMetadata(LLVMContext::MD_nofree)) + return false; + const Function *F = nullptr; if (auto *I = dyn_cast<Instruction>(this)) F = I->getFunction(); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 4eb4b58d022e..81a53722f489 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -119,6 +119,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ModRef.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -399,6 +400,7 @@ public: bool hasBrokenDebugInfo() const { return BrokenDebugInfo; } bool verify(const Function &F) { + llvm::TimeTraceScope timeScope("Verifier"); assert(F.getParent() == &M && "An instance of this class only works with a specific module!"); @@ -526,6 +528,7 @@ private: void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitNoaliasAddrspaceMetadata(Instruction &I, MDNode *Range, Type *Ty); void visitDereferenceableMetadata(Instruction &I, MDNode *MD); + void visitNofreeMetadata(Instruction &I, MDNode *MD); void visitProfMetadata(Instruction &I, MDNode *MD); void visitCallStackMetadata(MDNode *MD); void visitMemProfMetadata(Instruction &I, MDNode *MD); @@ -1298,9 +1301,11 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) { if (N.getTag() == dwarf::DW_TAG_set_type) { if (auto *T = N.getRawBaseType()) { auto *Enum = dyn_cast_or_null<DICompositeType>(T); + auto *Subrange = dyn_cast_or_null<DISubrangeType>(T); auto *Basic = dyn_cast_or_null<DIBasicType>(T); CheckDI( (Enum && Enum->getTag() == dwarf::DW_TAG_enumeration_type) || + (Subrange && Subrange->getTag() == dwarf::DW_TAG_subrange_type) || (Basic && (Basic->getEncoding() == dwarf::DW_ATE_unsigned || Basic->getEncoding() == dwarf::DW_ATE_signed || Basic->getEncoding() == dwarf::DW_ATE_unsigned_char || @@ -2443,16 +2448,6 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs, CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V); } - // Check EVEX512 feature. - if (TT.isX86() && MaxParameterWidth >= 512) { - Attribute TargetFeaturesAttr = Attrs.getFnAttr("target-features"); - if (TargetFeaturesAttr.isValid()) { - StringRef TF = TargetFeaturesAttr.getValueAsString(); - Check(!TF.contains("+avx512f") || !TF.contains("-evex512"), - "512-bit vector arguments require 'evex512' for AVX512", V); - } - } - checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-prefix", V); checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-entry", V); if (Attrs.hasFnAttr("patchable-function-entry-section")) @@ -2526,12 +2521,11 @@ void Verifier::verifyFunctionMetadata( for (const auto &Pair : MDs) { if (Pair.first == LLVMContext::MD_prof) { MDNode *MD = Pair.second; - if (isExplicitlyUnknownBranchWeightsMetadata(*MD)) { - CheckFailed("'unknown' !prof metadata should appear only on " - "instructions supporting the 'branch_weights' metadata", - MD); + // We may have functions that are synthesized by the compiler, e.g. in + // WPD, that we can't currently determine the entry count. + if (isExplicitlyUnknownProfileMetadata(*MD)) continue; - } + Check(MD->getNumOperands() >= 2, "!prof annotations should have no less than 2 operands", MD); @@ -2830,6 +2824,7 @@ static Instruction *getSuccPad(Instruction *Terminator) { } void Verifier::verifySiblingFuncletUnwinds() { + llvm::TimeTraceScope timeScope("Verifier verify sibling funclet unwinds"); SmallPtrSet<Instruction *, 8> Visited; SmallPtrSet<Instruction *, 8> Active; for (const auto &Pair : SiblingFuncletInfo) { @@ -3006,7 +3001,7 @@ void Verifier::visitFunction(const Function &F) { if (!IsIntrinsic) { Check(!Arg.getType()->isMetadataTy(), "Function takes metadata but isn't an intrinsic", &Arg, &F); - Check(!Arg.getType()->isTokenTy(), + Check(!Arg.getType()->isTokenLikeTy(), "Function takes token but isn't an intrinsic", &Arg, &F); Check(!Arg.getType()->isX86_AMXTy(), "Function takes x86_amx but isn't an intrinsic", &Arg, &F); @@ -3020,7 +3015,7 @@ void Verifier::visitFunction(const Function &F) { } if (!IsIntrinsic) { - Check(!F.getReturnType()->isTokenTy(), + Check(!F.getReturnType()->isTokenLikeTy(), "Function returns a token but isn't an intrinsic", &F); Check(!F.getReturnType()->isX86_AMXTy(), "Function returns a x86_amx but isn't an intrinsic", &F); @@ -3190,7 +3185,7 @@ void Verifier::visitFunction(const Function &F) { // Scope and SP could be the same MDNode and we don't want to skip // validation in that case - if (SP && ((Scope != SP) && !Seen.insert(SP).second)) + if ((Scope != SP) && !Seen.insert(SP).second) return; CheckDI(SP->describes(&F), @@ -3634,7 +3629,7 @@ void Verifier::visitPHINode(PHINode &PN) { "PHI nodes not grouped at top of basic block!", &PN, PN.getParent()); // Check that a PHI doesn't yield a Token. - Check(!PN.getType()->isTokenTy(), "PHI nodes cannot have token type!"); + Check(!PN.getType()->isTokenLikeTy(), "PHI nodes cannot have token type!"); // Check that all of the values of the PHI node have the same type as the // result. @@ -3839,14 +3834,14 @@ void Verifier::visitCallBase(CallBase &Call) { for (Type *ParamTy : FTy->params()) { Check(!ParamTy->isMetadataTy(), "Function has metadata parameter but isn't an intrinsic", Call); - Check(!ParamTy->isTokenTy(), + Check(!ParamTy->isTokenLikeTy(), "Function has token parameter but isn't an intrinsic", Call); } } // Verify that indirect calls don't return tokens. if (!Call.getCalledFunction()) { - Check(!FTy->getReturnType()->isTokenTy(), + Check(!FTy->getReturnType()->isTokenLikeTy(), "Return type cannot be token for indirect call!"); Check(!FTy->getReturnType()->isX86_AMXTy(), "Return type cannot be x86_amx for indirect call!"); @@ -5021,6 +5016,13 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) { &I); } +void Verifier::visitNofreeMetadata(Instruction &I, MDNode *MD) { + Check(I.getType()->isPointerTy(), "nofree applies only to pointer types", &I); + Check((isa<IntToPtrInst>(I)), "nofree applies only to inttoptr instruction", + &I); + Check(MD->getNumOperands() == 0, "nofree metadata must be empty", &I); +} + void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { auto GetBranchingTerminatorNumOperands = [&]() { unsigned ExpectedNumOperands = 0; @@ -5496,6 +5498,9 @@ void Verifier::visitInstruction(Instruction &I) { if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) visitDereferenceableMetadata(I, MD); + if (MDNode *MD = I.getMetadata(LLVMContext::MD_nofree)) + visitNofreeMetadata(I, MD); + if (MDNode *TBAA = I.getMetadata(LLVMContext::MD_tbaa)) TBAAVerifyHelper.visitTBAAMetadata(I, TBAA); @@ -6724,7 +6729,9 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { "invalid vector type for format", &Call, Src1, Call.getArgOperand(5)); break; } - case Intrinsic::amdgcn_wmma_f32_16x16x128_f8f6f4: { + case Intrinsic::amdgcn_wmma_f32_16x16x128_f8f6f4: + case Intrinsic::amdgcn_wmma_scale_f32_16x16x128_f8f6f4: + case Intrinsic::amdgcn_wmma_scale16_f32_16x16x128_f8f6f4: { Value *Src0 = Call.getArgOperand(1); Value *Src1 = Call.getArgOperand(3); @@ -6772,6 +6779,28 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { "invalid vector type for format", &Call, Src1, Call.getArgOperand(2)); break; } + case Intrinsic::amdgcn_cooperative_atomic_load_32x4B: + case Intrinsic::amdgcn_cooperative_atomic_load_16x8B: + case Intrinsic::amdgcn_cooperative_atomic_load_8x16B: + case Intrinsic::amdgcn_cooperative_atomic_store_32x4B: + case Intrinsic::amdgcn_cooperative_atomic_store_16x8B: + case Intrinsic::amdgcn_cooperative_atomic_store_8x16B: { + // Check we only use this intrinsic on the FLAT or GLOBAL address spaces. + Value *PtrArg = Call.getArgOperand(0); + const unsigned AS = PtrArg->getType()->getPointerAddressSpace(); + Check(AS == AMDGPUAS::FLAT_ADDRESS || AS == AMDGPUAS::GLOBAL_ADDRESS, + "cooperative atomic intrinsics require a generic or global pointer", + &Call, PtrArg); + + // Last argument must be a MD string + auto *Op = cast<MetadataAsValue>(Call.getArgOperand(Call.arg_size() - 1)); + MDNode *MD = cast<MDNode>(Op->getMetadata()); + Check((MD->getNumOperands() == 1) && isa<MDString>(MD->getOperand(0)), + "cooperative atomic intrinsics require that the last argument is a " + "metadata string", + &Call, Op); + break; + } case Intrinsic::nvvm_setmaxnreg_inc_sync_aligned_u32: case Intrinsic::nvvm_setmaxnreg_dec_sync_aligned_u32: { Value *V = Call.getArgOperand(0); |
