[llvm] Add support for metadata attachments for Function Arguments (PR #78893)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 21 01:43:46 PST 2024
https://github.com/andjo403 created https://github.com/llvm/llvm-project/pull/78893
This patch adds an IR, assembly and bitcode representation for metadata attachments for Function Arguments.
Have been noticed multiple times in rust that it is not possible to add range metadata to Function Arguments so this is the first part to support that.
cc https://github.com/rust-lang/rust/issues/50156
cc https://github.com/llvm/llvm-project/issues/76628
First time contributor to llvm so not sure about the process to add reviewers or if there needs to be some RFC or something like that.
>From de99679776c25382dae5b9ebc2f003d5137a97a4 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at users.noreply.github.com>
Date: Sun, 21 Jan 2024 10:17:33 +0100
Subject: [PATCH] Add support for metadata attachments for Function Arguments
This patch adds an IR, assembly and bitcode representation for metadata
attachments for Function Arguments.
---
llvm/docs/LangRef.rst | 11 +++---
llvm/include/llvm/AsmParser/LLParser.h | 8 +++-
llvm/include/llvm/Bitcode/LLVMBitCodes.h | 1 +
llvm/include/llvm/IR/Argument.h | 8 ++++
llvm/lib/AsmParser/LLParser.cpp | 23 ++++++++++-
llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 44 +++++++++++++++++++--
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 38 +++++++++++++++++-
llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 7 +++-
llvm/lib/IR/AsmWriter.cpp | 24 +++++++++++
llvm/lib/IR/Metadata.cpp | 6 ++-
llvm/test/Assembler/metadata-decl.ll | 12 +++++-
llvm/test/Assembler/metadata.ll | 9 +++++
12 files changed, 172 insertions(+), 19 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index bc9cfb557c54090..dfbba476dbc45a9 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -319,7 +319,7 @@ added in the future:
not be used lightly but only for specific situations such as an
alternative to the *register pinning* performance technique often
used when implementing functional programming languages. At the
- moment only X86, AArch64, and RISCV support this convention. The
+ moment only X86, AArch64, and RISCV support this convention. The
following limitations exist:
- On *X86-32* only up to 4 bit type parameters are supported. No
@@ -643,10 +643,10 @@ implementation defined, the optimizer can't do the latter. The former is
challenging as many commonly expected properties, such as
``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types.
Similar restrictions apply to intrinsics that might examine the pointer bits,
-such as :ref:`llvm.ptrmask<int_ptrmask>`.
+such as :ref:`llvm.ptrmask<int_ptrmask>`.
The alignment information provided by the frontend for a non-integral pointer
-(typically using attributes or metadata) must be valid for every possible
+(typically using attributes or metadata) must be valid for every possible
representation of the pointer.
.. _globalvars:
@@ -824,7 +824,8 @@ an optional :ref:`calling convention <callingconv>`,
an optional ``unnamed_addr`` attribute, a return type, an optional
:ref:`parameter attribute <paramattrs>` for the return type, a function
name, a (possibly empty) argument list (each with optional :ref:`parameter
-attributes <paramattrs>`), optional :ref:`function attributes <fnattrs>`,
+attributes <paramattrs>` and an optional list of attached :ref:`metadata <metadata>`),
+optional :ref:`function attributes <fnattrs>`,
an optional address space, an optional section, an optional partition,
an optional alignment, an optional :ref:`comdat <langref_comdats>`,
an optional :ref:`garbage collector name <gc>`, an optional :ref:`prefix <prefixdata>`,
@@ -848,7 +849,7 @@ argument is of the following form:
Syntax::
- <type> [parameter Attrs] [name]
+ <type> [parameter Attrs] (!name !N)* [name]
LLVM function declarations consist of the "``declare``" keyword, an
optional :ref:`linkage type <linkage>`, an optional :ref:`visibility style
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index cf358c384f52033..15c8a4cf354b67a 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -285,6 +285,8 @@ namespace llvm {
};
bool parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
bool InAttrGroup);
+ bool parseOptionalParamMetadata(
+ SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs);
bool parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam);
bool parseOptionalParamAttrs(AttrBuilder &B) {
return parseOptionalParamOrReturnAttrs(B, true);
@@ -607,8 +609,10 @@ namespace llvm {
Type *Ty;
AttributeSet Attrs;
std::string Name;
- ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N)
- : Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+ ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N,
+ const SmallVector<std::pair<unsigned, MDNode *>, 8> &mds)
+ : Loc(L), Ty(ty), Attrs(Attr), Name(N), MDs(mds) {}
};
bool parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
SmallVectorImpl<unsigned> &UnnamedArgNums,
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index c6f0ddf29a6da88..c3c968d4d0cb49a 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -369,6 +369,7 @@ enum MetadataCodes {
METADATA_GENERIC_SUBRANGE = 45, // [distinct, count, lo, up, stride]
METADATA_ARG_LIST = 46, // [n x [type num, value num]]
METADATA_ASSIGN_ID = 47, // [distinct, ...]
+ METADATA_PARAM_ATTACHMENT = 48, // [ [valueid ,] [valueid, [n x [id, mdnode]]]
};
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h
index f0c0ce75d2b7e18..02209eba2d8be0d 100644
--- a/llvm/include/llvm/IR/Argument.h
+++ b/llvm/include/llvm/IR/Argument.h
@@ -177,6 +177,14 @@ class Argument final : public Value {
static bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}
+
+ using Value::addMetadata;
+ using Value::clearMetadata;
+ using Value::eraseMetadata;
+ using Value::getAllMetadata;
+ using Value::getMetadata;
+ using Value::hasMetadata;
+ using Value::setMetadata;
};
} // End llvm namespace
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d6c5993797de111..728df9c6da35a94 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1929,6 +1929,19 @@ bool LLParser::parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam) {
}
}
+/// Parse a potentially empty list of parameter or return attributes.
+bool LLParser::parseOptionalParamMetadata(
+ SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) {
+ while (Lex.getKind() == lltok::MetadataVar) {
+ unsigned MDK;
+ MDNode *N;
+ if (parseMetadataAttachment(MDK, N))
+ return true;
+ MDs.emplace_back(MDK, N);
+ }
+ return false;
+}
+
static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) {
HasLinkage = true;
switch (Kind) {
@@ -3058,7 +3071,9 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
LocTy TypeLoc = Lex.getLoc();
Type *ArgTy = nullptr;
AttrBuilder Attrs(M->getContext());
- if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs))
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+ if (parseType(ArgTy) || parseOptionalParamAttrs(Attrs) ||
+ parseOptionalParamMetadata(MDs))
return true;
if (ArgTy->isVoidTy())
@@ -3087,7 +3102,7 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
ArgList.emplace_back(TypeLoc, ArgTy,
AttributeSet::get(ArgTy->getContext(), Attrs),
- std::move(Name));
+ std::move(Name), std::move(MDs));
} while (EatIfPresent(lltok::comma));
}
@@ -3115,6 +3130,8 @@ bool LLParser::parseFunctionType(Type *&Result) {
if (ArgList[i].Attrs.hasAttributes())
return error(ArgList[i].Loc,
"argument attributes invalid in function type");
+ if (!ArgList[i].MDs.empty())
+ return error(ArgList[i].Loc, "metadata invalid in function type");
}
SmallVector<Type*, 16> ArgListTy;
@@ -6223,6 +6240,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
// Add all of the arguments we parsed to the function.
Function::arg_iterator ArgIt = Fn->arg_begin();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
+ for (const auto &MD : ArgList[i].MDs)
+ ArgIt->addMetadata(MD.first, *MD.second);
// If the argument has a name, insert it into the argument symbol table.
if (ArgList[i].Name.empty()) continue;
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 770eb83af17f9b0..dbd741961dd3ab8 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -26,6 +26,7 @@
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/Bitstream/BitstreamReader.h"
+#include "llvm/IR/Argument.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
@@ -60,9 +61,6 @@
#include <type_traits>
#include <utility>
#include <vector>
-namespace llvm {
-class Argument;
-}
using namespace llvm;
@@ -477,6 +475,7 @@ class MetadataLoader::MetadataLoaderImpl {
function_ref<void(StringRef)> CallBack);
Error parseGlobalObjectAttachment(GlobalObject &GO,
ArrayRef<uint64_t> Record);
+ Error parseParamAttachment(Function &F, ArrayRef<uint64_t> Record);
Error parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
void resolveForwardRefsAndPlaceholders(PlaceholderQueue &Placeholders);
@@ -2263,6 +2262,19 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
+ case bitc::METADATA_PARAM_ATTACHMENT: {
+ unsigned RecordLength = Record.size();
+ if (Record.empty() || (RecordLength - 2) % 2 == 1)
+ return error("Invalid record");
+ unsigned ValueID = Record[0];
+ if (ValueID >= ValueList.size())
+ return error("Invalid record");
+ if (auto *F = dyn_cast<Function>(ValueList[ValueID]))
+ if (Error Err =
+ parseParamAttachment(*F, ArrayRef<uint64_t>(Record).slice(1)))
+ return Err;
+ break;
+ }
}
return Error::success();
#undef GET_OR_DISTINCT
@@ -2321,6 +2333,24 @@ Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment(
return Error::success();
}
+Error MetadataLoader::MetadataLoaderImpl::parseParamAttachment(
+ Function &F, ArrayRef<uint64_t> Record) {
+ assert((Record.size() - 1) % 2 == 0);
+
+ auto *A = F.getArg(Record[0]);
+ for (unsigned I = 1, E = Record.size(); I != E; I += 2) {
+ auto K = MDKindMap.find(Record[I]);
+ if (K == MDKindMap.end())
+ return error("Invalid ID");
+ MDNode *MD =
+ dyn_cast_or_null<MDNode>(getMetadataFwdRefOrLoad(Record[I + 1]));
+ if (!MD)
+ return error("Invalid metadata attachment: expect fwd ref to MDNode");
+ A->addMetadata(K->second, *MD);
+ }
+ return Error::success();
+}
+
/// Parse metadata attachments.
Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment(
Function &F, ArrayRef<Instruction *> InstructionList) {
@@ -2406,6 +2436,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment(
}
break;
}
+ case bitc::METADATA_PARAM_ATTACHMENT: {
+ unsigned RecordLength = Record.size();
+ if (Record.empty() || (RecordLength - 1) % 2 == 1)
+ return error("Invalid record");
+ if (Error Err = parseParamAttachment(F, Record))
+ return Err;
+ break;
+ }
}
}
}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a5fc267b1883bfe..9a9c4b413268e17 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -29,6 +29,7 @@
#include "llvm/Bitstream/BitCodes.h"
#include "llvm/Bitstream/BitstreamWriter.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Comdat.h"
@@ -378,6 +379,8 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
void writeFunctionMetadataAttachment(const Function &F);
void pushGlobalMetadataAttachment(SmallVectorImpl<uint64_t> &Record,
const GlobalObject &GO);
+ void pushParamMetadataAttachment(SmallVectorImpl<uint64_t> &Record,
+ const Argument &A);
void writeModuleMetadataKinds();
void writeOperandBundleTags();
void writeSyncScopeNames();
@@ -2393,8 +2396,17 @@ void ModuleBitcodeWriter::writeModuleMetadata() {
Stream.EmitRecord(bitc::METADATA_GLOBAL_DECL_ATTACHMENT, Record);
};
for (const Function &F : M)
- if (F.isDeclaration() && F.hasMetadata())
- AddDeclAttachedMetadata(F);
+ if (F.isDeclaration()) {
+ if (F.hasMetadata())
+ AddDeclAttachedMetadata(F);
+ for (const auto &A : F.args())
+ if (A.hasMetadata()) {
+ Record.push_back(VE.getValueID(&F));
+ pushParamMetadataAttachment(Record, A);
+ Stream.EmitRecord(bitc::METADATA_PARAM_ATTACHMENT, Record);
+ Record.clear();
+ }
+ }
// FIXME: Only store metadata for declarations here, and move data for global
// variable definitions to a separate block (PR28134).
for (const GlobalVariable &GV : M.globals())
@@ -2426,11 +2438,30 @@ void ModuleBitcodeWriter::pushGlobalMetadataAttachment(
}
}
+void ModuleBitcodeWriter::pushParamMetadataAttachment(
+ SmallVectorImpl<uint64_t> &Record, const Argument &A) {
+ Record.push_back(A.getArgNo());
+ // [n x [id, mdnode]]
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ A.getAllMetadata(MDs);
+ for (const auto &I : MDs) {
+ Record.push_back(I.first);
+ Record.push_back(VE.getMetadataID(I.second));
+ }
+}
+
void ModuleBitcodeWriter::writeFunctionMetadataAttachment(const Function &F) {
Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
SmallVector<uint64_t, 64> Record;
+ for (const auto &A : F.args())
+ if (A.hasMetadata()) {
+ pushParamMetadataAttachment(Record, A);
+ Stream.EmitRecord(bitc::METADATA_PARAM_ATTACHMENT, Record);
+ Record.clear();
+ }
+
if (F.hasMetadata()) {
pushGlobalMetadataAttachment(Record, F);
Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
@@ -3476,6 +3507,9 @@ void ModuleBitcodeWriter::writeFunction(
bool NeedsMetadataAttachment = F.hasMetadata();
+ for (auto IA = F.arg_begin(), E = F.arg_end(); IA != E; ++IA)
+ NeedsMetadataAttachment |= IA->hasMetadata();
+
DILocation *LastDL = nullptr;
SmallSetVector<Function *, 4> BlockAddressUsers;
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index fccb2a606f7ed9f..3f3b2fa23688ee6 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -398,8 +398,13 @@ ValueEnumerator::ValueEnumerator(const Module &M,
// Enumerate types used by function bodies and argument lists.
for (const Function &F : M) {
- for (const Argument &A : F.args())
+ for (const Argument &A : F.args()) {
EnumerateType(A.getType());
+ MDs.clear();
+ A.getAllMetadata(MDs);
+ for (const auto &I : MDs)
+ EnumerateMetadata(F.isDeclaration() ? nullptr : &F, I.second);
+ }
// Enumerate metadata attached to this function.
MDs.clear();
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 3c15784a0ed5eba..b4d7ff5b887b515 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -857,6 +857,9 @@ class SlotTracker : public AbstractSlotTrackerStorage {
/// Add all of the metadata from a function.
void processFunctionMetadata(const Function &F);
+ /// Add all of the metadata from a argument.
+ void processParamMetadata(const Argument &A);
+
/// Add all of the metadata from an instruction.
void processInstructionMetadata(const Instruction &I);
@@ -1128,6 +1131,9 @@ void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) {
void SlotTracker::processFunctionMetadata(const Function &F) {
processGlobalObjectMetadata(F);
+ for (const auto &A : F.args()) {
+ processParamMetadata(A);
+ }
for (auto &BB : F) {
for (auto &I : BB) {
for (const DPValue &DPV : I.getDbgValueRange())
@@ -1162,6 +1168,14 @@ void SlotTracker::processInstructionMetadata(const Instruction &I) {
CreateMetadataSlot(MD.second);
}
+void SlotTracker::processParamMetadata(const Argument &A) {
+ // Process metadata attached to this instruction.
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ A.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ CreateMetadataSlot(MD.second);
+}
+
/// Clean up after incorporating a function. This is the only way to get out of
/// the function incorporation state that affects get*Slot/Create*Slot. Function
/// incorporation state is indicated by TheFunction != 0.
@@ -3918,6 +3932,12 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << ' ';
writeAttributeSet(ArgAttrs);
}
+ auto *Arg = F->getArg(I);
+ if (Arg->hasMetadata()) {
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ Arg->getAllMetadata(MDs);
+ printMetadataAttachments(MDs, " ");
+ }
}
} else {
// The arguments are meaningful here, print them in detail.
@@ -4010,6 +4030,10 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
writeAttributeSet(Attrs);
}
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ Arg->getAllMetadata(MDs);
+ printMetadataAttachments(MDs, " ");
+
// Output name, if available...
if (Arg->hasName()) {
Out << ' ';
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 37017a222d4853d..bd02ca69723c0af 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1477,7 +1477,8 @@ void Value::getAllMetadata(
}
void Value::setMetadata(unsigned KindID, MDNode *Node) {
- assert(isa<Instruction>(this) || isa<GlobalObject>(this));
+ assert(isa<Instruction>(this) || isa<GlobalObject>(this) ||
+ isa<Argument>(this));
// Handle the case when we're adding/updating metadata on a value.
if (Node) {
@@ -1511,7 +1512,8 @@ void Value::setMetadata(StringRef Kind, MDNode *Node) {
}
void Value::addMetadata(unsigned KindID, MDNode &MD) {
- assert(isa<Instruction>(this) || isa<GlobalObject>(this));
+ assert(isa<Instruction>(this) || isa<GlobalObject>(this) ||
+ isa<Argument>(this));
if (!HasMetadata)
HasMetadata = true;
getContext().pImpl->ValueMetadata[this].insert(KindID, MD);
diff --git a/llvm/test/Assembler/metadata-decl.ll b/llvm/test/Assembler/metadata-decl.ll
index 4f28638fd0f182b..e7f249f114a6967 100644
--- a/llvm/test/Assembler/metadata-decl.ll
+++ b/llvm/test/Assembler/metadata-decl.ll
@@ -1,11 +1,19 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
; RUN: llvm-as < %s | llvm-dis -materialize-metadata | FileCheck %s
-; CHECK: @foo = external global i32, !foo !0
+; CHECK: @foo = external global i32, !foo [[M0:![0-9]+]]
@foo = external global i32, !foo !0
-; CHECK: declare !bar !1 void @bar()
+; CHECK: declare !bar [[M1:![0-9]+]] void @bar()
declare !bar !1 void @bar()
+; CHECK: declare void @test1(i32 noundef !foo [[M0]] !bar [[M1]], i32 !range [[M2:![0-9]+]])
+declare void @test1(i32 noundef !foo !0 !bar !1, i32 !range !2)
+
+; CHECK: [[M0]] = distinct !{}
+; CHECK: [[M1]] = distinct !{}
+; CHECK: [[M2]] = !{i32 1, i32 0}
+
!0 = distinct !{}
!1 = distinct !{}
+!2 = !{ i32 1, i32 0 }
diff --git a/llvm/test/Assembler/metadata.ll b/llvm/test/Assembler/metadata.ll
index 5b62bfafa6d7d8a..8efcf1909120314 100644
--- a/llvm/test/Assembler/metadata.ll
+++ b/llvm/test/Assembler/metadata.ll
@@ -26,6 +26,11 @@ define void @test3() !bar !3 {
unreachable, !bar !4
}
+; CHECK: define void @test4(i32 noundef !foo [[M2]] !baz [[M5:![0-9]+]] %a, i32 !range [[M6:![0-9]+]] %b)
+define void @test4(i32 noundef !foo !2 !baz !8 %a, i32 !range !9 %b) {
+ unreachable
+}
+
; CHECK-LABEL: define void @test_attachment_name() {
; CHECK: unreachable, !\342abc [[M4]]
define void @test_attachment_name() {
@@ -38,6 +43,8 @@ define void @test_attachment_name() {
; CHECK: [[M0]] = !DILocation
; CHECK: [[M1]] = distinct !DISubprogram
; CHECK: [[M4]] = distinct !{}
+; CHECK: [[M5]] = distinct !{}
+; CHECK: [[M6]] = !{i32 1, i32 0}
!llvm.module.flags = !{!7}
!llvm.dbg.cu = !{!5}
@@ -52,6 +59,8 @@ define void @test_attachment_name() {
splitDebugFilename: "abc.debug", emissionKind: 2)
!6 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = distinct !{}
+!9 = !{ i32 1, i32 0 }
declare void @llvm.dbg.func.start(metadata) nounwind readnone
More information about the llvm-commits
mailing list