[llvm] [RemoveDIs][DebugInfo][IR] Add parsing for non-intrinsic debug values (PR #79818)
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 4 09:02:00 PST 2024
https://github.com/SLTozer updated https://github.com/llvm/llvm-project/pull/79818
>From df8fa60b3b3c880ebb9c3bbc269d3cb2089cac61 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Mon, 29 Jan 2024 11:04:24 +0000
Subject: [PATCH 01/10] Add parsing for non-intrinsic debug values
---
llvm/include/llvm/AsmParser/LLParser.h | 4 +
llvm/include/llvm/AsmParser/LLToken.h | 3 +
.../include/llvm/IR/DebugProgramInstruction.h | 24 +++
llvm/lib/AsmParser/LLLexer.cpp | 18 ++-
llvm/lib/AsmParser/LLParser.cpp | 144 +++++++++++++++++-
llvm/lib/IR/DebugProgramInstruction.cpp | 17 +++
.../roundtrip-non-instruction-debug-info.ll | 87 +++++++++++
7 files changed, 295 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index f07f4c61f9d649..086f06e15c8627 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -178,6 +178,9 @@ namespace llvm {
/// UpgradeDebuginfo so it can generate broken bitcode.
bool UpgradeDebugInfo;
+ bool SeenNewDbgInfoFormat = false;
+ bool SeenOldDbgInfoFormat = false;
+
std::string SourceFileName;
public:
@@ -573,6 +576,7 @@ namespace llvm {
bool parseMDNodeTail(MDNode *&N);
bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
bool parseMetadataAttachment(unsigned &Kind, MDNode *&MD);
+ bool parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS);
bool parseInstructionMetadata(Instruction &Inst);
bool parseGlobalObjectMetadataAttachment(GlobalObject &GO);
bool parseOptionalFunctionMetadata(Function &F);
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 3c34706ee03e82..c860b17d764ff4 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -36,6 +36,7 @@ enum Kind {
exclaim, // !
bar, // |
colon, // :
+ hash, // #
kw_vscale,
kw_x,
@@ -483,6 +484,8 @@ enum Kind {
// Type valued tokens (TyVal).
Type,
+ DbgRecordType,
+
APFloat, // APFloatVal
APSInt // APSInt
};
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index cf30b4d0b0aaf0..33fff815d474f8 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -286,6 +286,30 @@ class DPValue : public DbgRecord, protected DebugValueUser {
DIAssignID *AssignID, Metadata *Address,
DIExpression *AddressExpression, const DILocation *DI);
+private:
+ /// Private constructor for creating new instances during parsing only. Only
+ /// called through `createUnresolvedDPValue` below, which makes clear that
+ /// this is used for parsing only, and will later return a subclass depending
+ /// on which Type is passed.
+ DPValue(LocationType Type, Metadata *Val, MDNode *Variable,
+ MDNode *Expression, MDNode *AssignID, Metadata *Address,
+ MDNode *AddressExpression, MDNode *DI);
+
+public:
+ /// Used to create DPValues during parsing, where some metadata references may
+ /// still be unresolved. Although for some fields a generic `Metadata*`
+ /// argument is accepted for forward type-references, the verifier and
+ /// accessors will reject incorrect types later on. The function is used for
+ /// all types of DPValues for simplicity while parsing, but asserts if any
+ /// necessary fields are empty or unused fields are not empty, i.e. if the
+ /// #dbg_assign fields are used for a non-dbg-assign type.
+ static DPValue *createUnresolvedDPValue(LocationType Type, Metadata *Val,
+ MDNode *Variable,
+ MDNode *Expression,
+ MDNode *AssignID, Metadata *Address,
+ MDNode *AddressExpression,
+ MDNode *DI);
+
static DPValue *createDPVAssign(Value *Val, DILocalVariable *Variable,
DIExpression *Expression,
DIAssignID *AssignID, Value *Address,
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 5d8a50eee13068..64bccc3e4bba3d 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -440,7 +440,9 @@ lltok::Kind LLLexer::LexCaret() {
/// AttrGrpID ::= #[0-9]+
lltok::Kind LLLexer::LexHash() {
// Handle AttrGrpID: #[0-9]+
- return LexUIntID(lltok::AttrGrpID);
+ if (isdigit(static_cast<unsigned char>(CurPtr[0])))
+ return LexUIntID(lltok::AttrGrpID);
+ return lltok::hash;
}
/// Lex a label, integer type, keyword, or hexadecimal integer constant.
@@ -923,6 +925,20 @@ lltok::Kind LLLexer::LexIdentifier() {
#undef DWKEYWORD
+// Keywords for debug record types.
+#define DBGRECORDTYPEKEYWORD(STR) \
+ do { \
+ if (Keyword == "dbg_" #STR) { \
+ StrVal = #STR; \
+ return lltok::DbgRecordType; \
+ } \
+ } while (false)
+
+ DBGRECORDTYPEKEYWORD(value);
+ DBGRECORDTYPEKEYWORD(declare);
+ DBGRECORDTYPEKEYWORD(assign);
+#undef DBGRECORDTYPEKEYWORD
+
if (Keyword.starts_with("DIFlag")) {
StrVal.assign(Keyword.begin(), Keyword.end());
return lltok::DIFlag;
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index a91e2f690999e0..c91a5520d8a5fd 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -62,6 +62,8 @@ static cl::opt<bool> AllowIncompleteIR(
"Allow incomplete IR on a best effort basis (references to unknown "
"metadata will be dropped)"));
+extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
+
static std::string getTypeString(Type *T) {
std::string Result;
raw_string_ostream Tmp(Result);
@@ -6041,6 +6043,17 @@ bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
return false;
}
+bool isOldDbgFormatIntrinsic(StringRef Name) {
+ // Exit early for the common (non-debug-intrinsic) case.
+ // We can make this the only check when we begin supporting all "llvm.dbg"
+ // intrinsics in the new debug info format.
+ if (!Name.starts_with("llvm.dbg."))
+ return false;
+ Intrinsic::ID FnID = Function::lookupIntrinsicID(Name);
+ return FnID == Intrinsic::dbg_declare || FnID == Intrinsic::dbg_value ||
+ FnID == Intrinsic::dbg_assign;
+}
+
/// FunctionHeader
/// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
/// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName
@@ -6228,6 +6241,13 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
}
}
+ if (isOldDbgFormatIntrinsic(FunctionName)) {
+ if (SeenNewDbgInfoFormat)
+ return error(NameLoc, "llvm.dbg intrinsic should not appear in a module "
+ "using non-intrinsic debug info");
+ SeenOldDbgInfoFormat = true;
+ }
+
Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace,
FunctionName, M);
@@ -6390,9 +6410,29 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
std::string NameStr;
- // parse the instructions in this block until we get a terminator.
+ // parse the instructions and debug values in this block until we get a
+ // terminator.
Instruction *Inst;
+ DPValue *DPV;
+ SmallVector<std::unique_ptr<DPValue>> TrailingDPValues;
do {
+ // Handle debug records first - there should always be an instruction
+ // following the debug records, i.e. they cannot appear after the block
+ // terminator.
+ while (Lex.getKind() == lltok::hash) {
+ if (SeenOldDbgInfoFormat)
+ return error(Lex.getLoc(), "debug record should not appear in a module "
+ "containing debug info intrinsics");
+ SeenNewDbgInfoFormat = true;
+ Lex.Lex();
+ if (!BB->getModule()->IsNewDbgInfoFormat)
+ BB->getModule()->convertToNewDbgValues();
+
+ if (parseDebugProgramValue(DPV, PFS))
+ return true;
+ TrailingDPValues.emplace_back(DPV);
+ }
+
// This instruction may have three possibilities for a name: a) none
// specified, b) name specified "%foo =", c) number specified: "%4 =".
LocTy NameLoc = Lex.getLoc();
@@ -6437,11 +6477,103 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// Set the name on the instruction.
if (PFS.setInstName(NameID, NameStr, NameLoc, Inst))
return true;
+
+ // Attach any preceding debug values to this instruction.
+ for (std::unique_ptr<DPValue> &DPV : TrailingDPValues) {
+ BB->insertDPValueBefore(DPV.release(), Inst->getIterator());
+ }
+ TrailingDPValues.clear();
} while (!Inst->isTerminator());
+ assert(TrailingDPValues.empty() &&
+ "All debug values should have been attached to an instruction.");
+
return false;
}
+/// parseDebugProgramValue
+/// ::= #dbg_Type { (ValueAsMetadata|DIArgList|MDNode), MetadataID,
+/// DIExpression, DILocation }
+bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
+ using LocType = DPValue::LocationType;
+ LocTy DPVLoc = Lex.getLoc();
+ if (Lex.getKind() != lltok::DbgRecordType) {
+ return error(DPVLoc, "expected debug record type here");
+ }
+ auto Type = StringSwitch<LocType>(Lex.getStrVal())
+ .Case("declare", LocType::Declare)
+ .Case("value", LocType::Value)
+ .Case("assign", LocType::Assign)
+ .Default(LocType::End);
+ if (Type == LocType::End)
+ return error(DPVLoc, "expected valid #dbg record here");
+ Lex.Lex();
+ if (parseToken(lltok::lbrace, "Expected '{' here"))
+ return true;
+
+ // Parse Value field...
+ Metadata *ValLocMD;
+ if (parseMetadata(ValLocMD, &PFS))
+ return true;
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+
+ // Parse Variable field...
+ MDNode *Variable;
+ if (parseMDNode(Variable))
+ return true;
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+
+ // Parse Expression field...
+ LocTy ExprLoc = Lex.getLoc();
+ Metadata *Expression;
+ if (parseMetadata(Expression, &PFS))
+ return true;
+ if (!isa<DIExpression>(Expression))
+ return error(ExprLoc, "expected valid DIExpression here");
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+
+ // Parse additional fields for #dbg_assign.
+ MDNode *AssignID = nullptr;
+ Metadata *AddressLocation = nullptr;
+ Metadata *AddressExpression = nullptr;
+ if (Type == LocType::Assign) {
+ // Parse DIAssignID...
+ if (parseMDNode(AssignID))
+ return true;
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+
+ // Parse address ValueAsMetadata...
+ if (parseMetadata(AddressLocation, &PFS))
+ return true;
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+
+ // Parse address DIExpression...
+ LocTy AddressExprLoc = Lex.getLoc();
+ if (parseMetadata(AddressExpression, &PFS))
+ return true;
+ if (!isa<DIExpression>(Expression))
+ return error(AddressExprLoc, "expected valid DIExpression here");
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+ }
+
+ /// Parse DILocation...
+ MDNode *DebugLoc;
+ if (parseMDNode(DebugLoc))
+ return true;
+
+ if (parseToken(lltok::rbrace, "Expected '}' here"))
+ return true;
+ DPV = DPValue::createUnresolvedDPValue(
+ Type, ValLocMD, Variable, cast<DIExpression>(Expression), AssignID,
+ AddressLocation, cast_or_null<DIExpression>(AddressExpression), DebugLoc);
+ return false;
+}
//===----------------------------------------------------------------------===//
// Instruction Parsing.
//===----------------------------------------------------------------------===//
@@ -7669,6 +7801,16 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
}
CI->setFastMathFlags(FMF);
}
+
+ if (CalleeID.Kind == ValID::t_GlobalName &&
+ isOldDbgFormatIntrinsic(CalleeID.StrVal)) {
+ if (SeenNewDbgInfoFormat) {
+ CI->deleteValue();
+ return error(CallLoc, "llvm.dbg intrinsic should not appear in a module "
+ "using non-intrinsic debug info");
+ }
+ SeenOldDbgInfoFormat = true;
+ }
CI->setAttributes(PAL);
ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
Inst = CI;
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index a8d64024e1797b..25cd82fb91f8c4 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -143,6 +143,23 @@ DPLabel::DPLabel(DILabel *Label, DebugLoc DL)
assert(Label && "Unexpected nullptr");
}
+DPValue::DPValue(DPValue::LocationType Type, Metadata *Val, MDNode *Variable,
+ MDNode *Expression, MDNode *AssignID, Metadata *Address,
+ MDNode *AddressExpression, MDNode *DI)
+ : DebugValueUser({Val, Address, AssignID}), Variable(Variable),
+ Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
+ Type(Type) {}
+
+DPValue *DPValue::createUnresolvedDPValue(DPValue::LocationType Type,
+ Metadata *Val, MDNode *Variable,
+ MDNode *Expression,
+ MDNode *AssignID, Metadata *Address,
+ MDNode *AddressExpression,
+ MDNode *DI) {
+ return new DPValue(Type, Val, Variable, Expression, AssignID, Address,
+ AddressExpression, DI);
+}
+
DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
DIExpression *Expr, const DILocation *DI) {
return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
diff --git a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
new file mode 100644
index 00000000000000..f8c0024977bc22
--- /dev/null
+++ b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
@@ -0,0 +1,87 @@
+;; Test that we can write in the old debug info format.
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=false < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+
+;; Test that we can write in the new debug info format...
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+
+;; ...and then read the new format and write the old format.
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
+; RUN: | opt --passes=verify -S --write-experimental-debuginfo=false \
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+
+;; Test also that the new flag is independent of the flag that enables use of
+;; these non-instruction debug info during LLVM passes.
+; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=false < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=true < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+
+; CHECK: @f(i32 %[[VAL_A:[0-9a-zA-Z]+]])
+; CHECK-NEXT: entry:
+; OLDDBG-NEXT: call void @llvm.dbg.value(metadata i32 %[[VAL_A]], metadata ![[VAR_A:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_1:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_value { i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]] }
+; CHECK-NEXT: {{^}} %[[VAL_B:[0-9a-zA-Z]+]] = alloca
+; OLDDBG-NEXT: call void @llvm.dbg.declare(metadata ptr %[[VAL_B]], metadata ![[VAR_B:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_2:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_declare { ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]] }
+; CHECK-NEXT: {{^}} %[[VAL_ADD:[0-9a-zA-Z]+]] = add i32 %[[VAL_A]], 5
+; OLDDBG-NEXT: call void @llvm.dbg.value(metadata !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), metadata ![[VAR_A]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg ![[LOC_3:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_value { !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]] }
+; CHECK-NEXT: {{^}} store i32 %[[VAL_ADD]]{{.+}}, !DIAssignID ![[ASSIGNID:[0-9]+]]
+; OLDDBG-NEXT: call void @llvm.dbg.assign(metadata i32 %[[VAL_ADD]], metadata ![[VAR_B]], metadata !DIExpression(), metadata ![[ASSIGNID]], metadata ptr %[[VAL_B]], metadata !DIExpression()), !dbg ![[LOC_4:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_assign { i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]] }
+; CHECK-NEXT: {{^}} ret i32
+
+; OLDDBG-DAG: declare void @llvm.dbg.value
+; OLDDBG-DAG: declare void @llvm.dbg.declare
+; OLDDBG-DAG: declare void @llvm.dbg.assign
+
+; CHECK-DAG: llvm.dbg.cu
+; CHECK-DAG: ![[VAR_A]] = !DILocalVariable(name: "a"
+; CHECK-DAG: ![[VAR_B]] = !DILocalVariable(name: "b"
+; CHECK-DAG: ![[LOC_1]] = !DILocation(line: 3, column: 15
+; CHECK-DAG: ![[LOC_2]] = !DILocation(line: 3, column: 20
+; CHECK-DAG: ![[LOC_3]] = !DILocation(line: 3, column: 25
+; CHECK-DAG: ![[LOC_4]] = !DILocation(line: 3, column: 30
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ call void @llvm.dbg.value(metadata i32 %a, metadata !20, metadata !DIExpression()), !dbg !30
+ %b = alloca i32, !dbg !30, !DIAssignID !40
+ call void @llvm.dbg.declare(metadata ptr %b, metadata !21, metadata !DIExpression()), !dbg !31
+ %add = add i32 %a, 5, !dbg !31
+ call void @llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %add), metadata !20, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !32
+ store i32 %add, ptr %b, !dbg !32, !DIAssignID !40
+ call void @llvm.dbg.assign(metadata i32 %add, metadata !21, metadata !DIExpression(), metadata !40, metadata ptr %b, metadata !DIExpression()), !dbg !33
+ ret i32 %add, !dbg !33
+
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!12, !12}
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !{!20, !21}
+!20 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !12)
+!21 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !12)
+!30 = !DILocation(line: 3, column: 15, scope: !7)
+!31 = !DILocation(line: 3, column: 20, scope: !7)
+!32 = !DILocation(line: 3, column: 25, scope: !7)
+!33 = !DILocation(line: 3, column: 30, scope: !7)
+!40 = distinct !DIAssignID()
\ No newline at end of file
>From 617b5298f74bf7434c98848e58bea6eeff83713c Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Mon, 29 Jan 2024 16:02:50 +0000
Subject: [PATCH 02/10] Address review nits
---
llvm/lib/AsmParser/LLParser.cpp | 45 ++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index c91a5520d8a5fd..d202ebaa86cf2a 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -71,6 +71,15 @@ static std::string getTypeString(Type *T) {
return Tmp.str();
}
+// Currently, we should always process modules in the old debug info format by
+// default regardless of the module's format in IR; convert it to the old format
+// here.
+bool finalizeDebugInfoFormat(Module *M) {
+ if (M)
+ M->setIsNewDbgInfoFormat(false);
+ return false;
+}
+
/// Run: module ::= toplevelentity*
bool LLParser::Run(bool UpgradeDebugInfo,
DataLayoutCallbackTy DataLayoutCallback) {
@@ -88,7 +97,7 @@ bool LLParser::Run(bool UpgradeDebugInfo,
}
return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
- validateEndOfIndex();
+ validateEndOfIndex() || finalizeDebugInfoFormat(M);
}
bool LLParser::parseStandaloneConstantValue(Constant *&C,
@@ -6410,10 +6419,9 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
std::string NameStr;
- // parse the instructions and debug values in this block until we get a
+ // Parse the instructions and debug values in this block until we get a
// terminator.
Instruction *Inst;
- DPValue *DPV;
SmallVector<std::unique_ptr<DPValue>> TrailingDPValues;
do {
// Handle debug records first - there should always be an instruction
@@ -6425,9 +6433,10 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
"containing debug info intrinsics");
SeenNewDbgInfoFormat = true;
Lex.Lex();
- if (!BB->getModule()->IsNewDbgInfoFormat)
- BB->getModule()->convertToNewDbgValues();
+ if (!M->IsNewDbgInfoFormat)
+ M->convertToNewDbgValues();
+ DPValue *DPV;
if (parseDebugProgramValue(DPV, PFS))
return true;
TrailingDPValues.emplace_back(DPV);
@@ -6479,9 +6488,8 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
return true;
// Attach any preceding debug values to this instruction.
- for (std::unique_ptr<DPValue> &DPV : TrailingDPValues) {
+ for (std::unique_ptr<DPValue> &DPV : TrailingDPValues)
BB->insertDPValueBefore(DPV.release(), Inst->getIterator());
- }
TrailingDPValues.clear();
} while (!Inst->isTerminator());
@@ -6492,14 +6500,15 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
}
/// parseDebugProgramValue
-/// ::= #dbg_Type { (ValueAsMetadata|DIArgList|MDNode), MetadataID,
-/// DIExpression, DILocation }
+/// ::= #dbg_Type '{' (ValueAsMetadata|DIArgList|MDNode) ',' MetadataID ','
+/// DIExpression ','
+/// (DIAssignID',' (ValueAsMetadata|MDNode)',' DIExpression] ',')?
+/// DILocation '}'
bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
using LocType = DPValue::LocationType;
LocTy DPVLoc = Lex.getLoc();
- if (Lex.getKind() != lltok::DbgRecordType) {
+ if (Lex.getKind() != lltok::DbgRecordType)
return error(DPVLoc, "expected debug record type here");
- }
auto Type = StringSwitch<LocType>(Lex.getStrVal())
.Case("declare", LocType::Declare)
.Case("value", LocType::Value)
@@ -6511,21 +6520,21 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
if (parseToken(lltok::lbrace, "Expected '{' here"))
return true;
- // Parse Value field...
+ // Parse Value field.
Metadata *ValLocMD;
if (parseMetadata(ValLocMD, &PFS))
return true;
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
- // Parse Variable field...
+ // Parse Variable field.
MDNode *Variable;
if (parseMDNode(Variable))
return true;
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
- // Parse Expression field...
+ // Parse Expression field.
LocTy ExprLoc = Lex.getLoc();
Metadata *Expression;
if (parseMetadata(Expression, &PFS))
@@ -6540,19 +6549,19 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
Metadata *AddressLocation = nullptr;
Metadata *AddressExpression = nullptr;
if (Type == LocType::Assign) {
- // Parse DIAssignID...
+ // Parse DIAssignID.
if (parseMDNode(AssignID))
return true;
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
- // Parse address ValueAsMetadata...
+ // Parse address ValueAsMetadata.
if (parseMetadata(AddressLocation, &PFS))
return true;
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
- // Parse address DIExpression...
+ // Parse address DIExpression.
LocTy AddressExprLoc = Lex.getLoc();
if (parseMetadata(AddressExpression, &PFS))
return true;
@@ -6562,7 +6571,7 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
return true;
}
- /// Parse DILocation...
+ /// Parse DILocation.
MDNode *DebugLoc;
if (parseMDNode(DebugLoc))
return true;
>From c6e5affd09e3e2d4ca984326bb449717afad176b Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Mon, 29 Jan 2024 16:22:47 +0000
Subject: [PATCH 03/10] Add tests, use brackets, minor fixes
---
llvm/lib/AsmParser/LLParser.cpp | 17 ++++----
llvm/test/Assembler/dbg-removedi-invalid-0.ll | 38 ++++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-1.ll | 39 +++++++++++++++++++
.../test/Assembler/dbg-removedi-invalid-10.ll | 36 +++++++++++++++++
.../test/Assembler/dbg-removedi-invalid-11.ll | 35 +++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-2.ll | 38 ++++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-3.ll | 39 +++++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-4.ll | 36 +++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-5.ll | 37 ++++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-6.ll | 37 ++++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-7.ll | 36 +++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-8.ll | 36 +++++++++++++++++
llvm/test/Assembler/dbg-removedi-invalid-9.ll | 36 +++++++++++++++++
.../roundtrip-non-instruction-debug-info.ll | 8 ++--
14 files changed, 457 insertions(+), 11 deletions(-)
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-0.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-1.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-10.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-11.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-2.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-3.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-4.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-5.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-6.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-7.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-8.ll
create mode 100644 llvm/test/Assembler/dbg-removedi-invalid-9.ll
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d202ebaa86cf2a..a71f2520059360 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6514,10 +6514,13 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
.Case("value", LocType::Value)
.Case("assign", LocType::Assign)
.Default(LocType::End);
- if (Type == LocType::End)
- return error(DPVLoc, "expected valid #dbg record here");
+ // If the file contained an invalid debug record type then parsing should fail
+ // above; the assert here should only fire if the Lexer gives us an invalid
+ // value.
+ assert(Type != LocType::End &&
+ "Lexer returned an invalid DbgRecordType string.");
Lex.Lex();
- if (parseToken(lltok::lbrace, "Expected '{' here"))
+ if (parseToken(lltok::lparen, "Expected '(' here"))
return true;
// Parse Value field.
@@ -6540,7 +6543,7 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
if (parseMetadata(Expression, &PFS))
return true;
if (!isa<DIExpression>(Expression))
- return error(ExprLoc, "expected valid DIExpression here");
+ return error(ExprLoc, "expected valid inline DIExpression here");
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
@@ -6565,8 +6568,8 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
LocTy AddressExprLoc = Lex.getLoc();
if (parseMetadata(AddressExpression, &PFS))
return true;
- if (!isa<DIExpression>(Expression))
- return error(AddressExprLoc, "expected valid DIExpression here");
+ if (!isa<DIExpression>(AddressExpression))
+ return error(AddressExprLoc, "expected valid inline DIExpression here");
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
}
@@ -6576,7 +6579,7 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
if (parseMDNode(DebugLoc))
return true;
- if (parseToken(lltok::rbrace, "Expected '}' here"))
+ if (parseToken(lltok::rparen, "Expected ')' here"))
return true;
DPV = DPValue::createUnresolvedDPValue(
Type, ValLocMD, Variable, cast<DIExpression>(Expression), AssignID,
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-0.ll b/llvm/test/Assembler/dbg-removedi-invalid-0.ll
new file mode 100644
index 00000000000000..feb513a405f9ec
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-0.ll
@@ -0,0 +1,38 @@
+;; Test that we get a parser error when a debug record appears post-terminator.
+;; Note: From the parser's perspective, the error is that the debug record is
+;; appearing at the start of a new unnamed basic block which contains no actual
+;; instructions.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ ret i32 %a, !dbg !18
+ #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+; CHECK: <stdin>:[[@LINE+1]]:1: error: expected instruction opcode
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-1.ll b/llvm/test/Assembler/dbg-removedi-invalid-1.ll
new file mode 100644
index 00000000000000..7ab5751777e8cf
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-1.ll
@@ -0,0 +1,39 @@
+;; Test that we get a parser error when a debug intrinsic appears in the same
+;; module as a debug record.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+; CHECK: <stdin>:[[@LINE+1]]:8: error: llvm.dbg intrinsic should not appear in a module using non-intrinsic debug info
+ call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata !DIExpression()), !dbg !14
+ ret i32 %a, !dbg !18
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-10.ll b/llvm/test/Assembler/dbg-removedi-invalid-10.ll
new file mode 100644
index 00000000000000..72dafcdb97fce4
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-10.ll
@@ -0,0 +1,36 @@
+;; Test that we get a parser error when we have a debug record with an
+;; incorrect number of arguments.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:46: error: expected '!' here
+ #dbg_value(i32 %a, !12, !DIExpression(), i32 0)
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-11.ll b/llvm/test/Assembler/dbg-removedi-invalid-11.ll
new file mode 100644
index 00000000000000..5ea588b87668c4
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-11.ll
@@ -0,0 +1,35 @@
+;; Test that we get a parser error when a basic block contains only a debug
+;; record.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+; CHECK: <stdin>:[[@LINE+1]]:1: error: expected instruction opcode
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-2.ll b/llvm/test/Assembler/dbg-removedi-invalid-2.ll
new file mode 100644
index 00000000000000..753a486e896b5a
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-2.ll
@@ -0,0 +1,38 @@
+;; Test that we get a parser error when a debug intrinsic declaration appears in
+;; the same module as a debug intrinsic declaration.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+ ret i32 %a, !dbg !18
+}
+
+; CHECK: <stdin>:[[@LINE+1]]:14: error: llvm.dbg intrinsic should not appear in a module using non-intrinsic debug info
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-3.ll b/llvm/test/Assembler/dbg-removedi-invalid-3.ll
new file mode 100644
index 00000000000000..e6f072373f54d5
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-3.ll
@@ -0,0 +1,39 @@
+;; Test that we get a parser error when a debug record appears in the same
+;; module as a debug intrinsic.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata !DIExpression()), !dbg !14
+; CHECK: <stdin>:[[@LINE+1]]:5: error: debug record should not appear in a module containing debug info intrinsics
+ #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+ ret i32 %a, !dbg !18
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-4.ll b/llvm/test/Assembler/dbg-removedi-invalid-4.ll
new file mode 100644
index 00000000000000..f898477603c8e2
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-4.ll
@@ -0,0 +1,36 @@
+;; Test that we get a parser error when we have a debug record with an invalid
+;; type.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:6: error: expected debug record type here
+ #dbg_invalid(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-5.ll b/llvm/test/Assembler/dbg-removedi-invalid-5.ll
new file mode 100644
index 00000000000000..2b3e3a763221d3
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-5.ll
@@ -0,0 +1,37 @@
+;; Test that we get a parser error when we have a debug record that does not use
+;; an inline DIExpression.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:29: error: expected valid inline DIExpression here
+ #dbg_value(i32 %a, !12, !20, !14)
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
+!20 = !DIExpression()
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-6.ll b/llvm/test/Assembler/dbg-removedi-invalid-6.ll
new file mode 100644
index 00000000000000..9aff3c79d79bb5
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-6.ll
@@ -0,0 +1,37 @@
+;; Test that we get a parser error when we have a debug assign record that does
+;; not use an inline DIExpression for its address expression.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:63: error: expected valid inline DIExpression here
+ #dbg_assign(i32 %a, !12, !DIExpression(), !15, ptr undef, !20, !14)
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
+!20 = !DIExpression()
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-7.ll b/llvm/test/Assembler/dbg-removedi-invalid-7.ll
new file mode 100644
index 00000000000000..036a85a2977fc7
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-7.ll
@@ -0,0 +1,36 @@
+;; Test that we get a parser error when we have a debug record with an incorrect
+;; number of arguments.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:44: error: Expected ',' here
+ #dbg_value(i32 %a, !12, !DIExpression())
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-8.ll b/llvm/test/Assembler/dbg-removedi-invalid-8.ll
new file mode 100644
index 00000000000000..d0b8f36d7895c5
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-8.ll
@@ -0,0 +1,36 @@
+;; Test that we get a parser error when we have a debug assign record with an
+;; incorrect number of arguments.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:50: error: Expected ',' here
+ #dbg_assign(i32 %a, !12, !DIExpression(), !14)
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-9.ll b/llvm/test/Assembler/dbg-removedi-invalid-9.ll
new file mode 100644
index 00000000000000..a019f73feab9c5
--- /dev/null
+++ b/llvm/test/Assembler/dbg-removedi-invalid-9.ll
@@ -0,0 +1,36 @@
+;; Test that we get a parser error when we have a debug record with an
+;; incorrect number of arguments.
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+; CHECK: <stdin>:[[@LINE+1]]:24: error: expected '!' here
+ #dbg_value(i32 %a, i32 0, !DIExpression(), !14)
+ ret i32 %a, !dbg !18
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12, !13}
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
+!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
+!14 = !DILocation(line: 3, column: 15, scope: !7)
+!15 = distinct !DIAssignID()
+!16 = !DILocation(line: 3, column: 20, scope: !7)
+!17 = !DILocation(line: 3, column: 25, scope: !7)
+!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
index f8c0024977bc22..6efffb431aa687 100644
--- a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
+++ b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
@@ -21,16 +21,16 @@
; CHECK: @f(i32 %[[VAL_A:[0-9a-zA-Z]+]])
; CHECK-NEXT: entry:
; OLDDBG-NEXT: call void @llvm.dbg.value(metadata i32 %[[VAL_A]], metadata ![[VAR_A:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_1:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_value { i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_value(i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]])
; CHECK-NEXT: {{^}} %[[VAL_B:[0-9a-zA-Z]+]] = alloca
; OLDDBG-NEXT: call void @llvm.dbg.declare(metadata ptr %[[VAL_B]], metadata ![[VAR_B:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_2:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_declare { ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_declare(ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]])
; CHECK-NEXT: {{^}} %[[VAL_ADD:[0-9a-zA-Z]+]] = add i32 %[[VAL_A]], 5
; OLDDBG-NEXT: call void @llvm.dbg.value(metadata !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), metadata ![[VAR_A]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg ![[LOC_3:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_value { !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_value(!DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]])
; CHECK-NEXT: {{^}} store i32 %[[VAL_ADD]]{{.+}}, !DIAssignID ![[ASSIGNID:[0-9]+]]
; OLDDBG-NEXT: call void @llvm.dbg.assign(metadata i32 %[[VAL_ADD]], metadata ![[VAR_B]], metadata !DIExpression(), metadata ![[ASSIGNID]], metadata ptr %[[VAL_B]], metadata !DIExpression()), !dbg ![[LOC_4:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_assign { i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_assign(i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]])
; CHECK-NEXT: {{^}} ret i32
; OLDDBG-DAG: declare void @llvm.dbg.value
>From ac969d371896da256701e16baf7a1f7a9632a551 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Thu, 22 Feb 2024 15:51:02 +0000
Subject: [PATCH 04/10] Rename tests, adjust lexer/token descriptions
---
llvm/include/llvm/AsmParser/LLToken.h | 3 +--
llvm/lib/AsmParser/LLLexer.cpp | 1 +
llvm/lib/AsmParser/LLParser.cpp | 6 ++----
...g-removedi-invalid-0.ll => dbg-record-invalid-0.ll} | 0
...g-removedi-invalid-1.ll => dbg-record-invalid-1.ll} | 0
...removedi-invalid-10.ll => dbg-record-invalid-10.ll} | 0
...removedi-invalid-11.ll => dbg-record-invalid-11.ll} | 0
...g-removedi-invalid-2.ll => dbg-record-invalid-2.ll} | 0
...g-removedi-invalid-3.ll => dbg-record-invalid-3.ll} | 0
...g-removedi-invalid-4.ll => dbg-record-invalid-4.ll} | 0
...g-removedi-invalid-5.ll => dbg-record-invalid-5.ll} | 0
...g-removedi-invalid-6.ll => dbg-record-invalid-6.ll} | 0
...g-removedi-invalid-7.ll => dbg-record-invalid-7.ll} | 0
...g-removedi-invalid-8.ll => dbg-record-invalid-8.ll} | 0
...g-removedi-invalid-9.ll => dbg-record-invalid-9.ll} | 0
.../DebugInfo/roundtrip-non-instruction-debug-info.ll | 10 +++++-----
16 files changed, 9 insertions(+), 11 deletions(-)
rename llvm/test/Assembler/{dbg-removedi-invalid-0.ll => dbg-record-invalid-0.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-1.ll => dbg-record-invalid-1.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-10.ll => dbg-record-invalid-10.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-11.ll => dbg-record-invalid-11.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-2.ll => dbg-record-invalid-2.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-3.ll => dbg-record-invalid-3.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-4.ll => dbg-record-invalid-4.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-5.ll => dbg-record-invalid-5.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-6.ll => dbg-record-invalid-6.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-7.ll => dbg-record-invalid-7.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-8.ll => dbg-record-invalid-8.ll} (100%)
rename llvm/test/Assembler/{dbg-removedi-invalid-9.ll => dbg-record-invalid-9.ll} (100%)
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index c860b17d764ff4..5863a8d6e8ee84 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -480,12 +480,11 @@ enum Kind {
DISPFlag, // DISPFlagFoo
DwarfMacinfo, // DW_MACINFO_foo
ChecksumKind, // CSK_foo
+ DbgRecordType, // dbg_foo
// Type valued tokens (TyVal).
Type,
- DbgRecordType,
-
APFloat, // APFloatVal
APSInt // APSInt
};
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 64bccc3e4bba3d..632bc404dce0bb 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -438,6 +438,7 @@ lltok::Kind LLLexer::LexCaret() {
/// Lex all tokens that start with a # character.
/// AttrGrpID ::= #[0-9]+
+/// Hash ::= #
lltok::Kind LLLexer::LexHash() {
// Handle AttrGrpID: #[0-9]+
if (isdigit(static_cast<unsigned char>(CurPtr[0])))
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index a71f2520059360..1556103e4ba598 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6500,10 +6500,8 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
}
/// parseDebugProgramValue
-/// ::= #dbg_Type '{' (ValueAsMetadata|DIArgList|MDNode) ',' MetadataID ','
-/// DIExpression ','
-/// (DIAssignID',' (ValueAsMetadata|MDNode)',' DIExpression] ',')?
-/// DILocation '}'
+/// ::= #dbg_type '(' Metadata ',' MDNode ',' Metadata ','
+/// (MDNode ',' Metadata ',' Metadata ',')? MDNode ')'
bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
using LocType = DPValue::LocationType;
LocTy DPVLoc = Lex.getLoc();
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-0.ll b/llvm/test/Assembler/dbg-record-invalid-0.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-0.ll
rename to llvm/test/Assembler/dbg-record-invalid-0.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-1.ll b/llvm/test/Assembler/dbg-record-invalid-1.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-1.ll
rename to llvm/test/Assembler/dbg-record-invalid-1.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-10.ll b/llvm/test/Assembler/dbg-record-invalid-10.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-10.ll
rename to llvm/test/Assembler/dbg-record-invalid-10.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-11.ll b/llvm/test/Assembler/dbg-record-invalid-11.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-11.ll
rename to llvm/test/Assembler/dbg-record-invalid-11.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-2.ll b/llvm/test/Assembler/dbg-record-invalid-2.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-2.ll
rename to llvm/test/Assembler/dbg-record-invalid-2.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-3.ll b/llvm/test/Assembler/dbg-record-invalid-3.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-3.ll
rename to llvm/test/Assembler/dbg-record-invalid-3.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-4.ll b/llvm/test/Assembler/dbg-record-invalid-4.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-4.ll
rename to llvm/test/Assembler/dbg-record-invalid-4.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-5.ll b/llvm/test/Assembler/dbg-record-invalid-5.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-5.ll
rename to llvm/test/Assembler/dbg-record-invalid-5.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-6.ll b/llvm/test/Assembler/dbg-record-invalid-6.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-6.ll
rename to llvm/test/Assembler/dbg-record-invalid-6.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-7.ll b/llvm/test/Assembler/dbg-record-invalid-7.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-7.ll
rename to llvm/test/Assembler/dbg-record-invalid-7.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-8.ll b/llvm/test/Assembler/dbg-record-invalid-8.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-8.ll
rename to llvm/test/Assembler/dbg-record-invalid-8.ll
diff --git a/llvm/test/Assembler/dbg-removedi-invalid-9.ll b/llvm/test/Assembler/dbg-record-invalid-9.ll
similarity index 100%
rename from llvm/test/Assembler/dbg-removedi-invalid-9.ll
rename to llvm/test/Assembler/dbg-record-invalid-9.ll
diff --git a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
index 6efffb431aa687..434864270f660d 100644
--- a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
+++ b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
@@ -1,22 +1,22 @@
;; Test that we can write in the old debug info format.
; RUN: opt --passes=verify -S --write-experimental-debuginfo=false < %s \
-; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg
;; Test that we can write in the new debug info format...
; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
-; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg
;; ...and then read the new format and write the old format.
; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
; RUN: | opt --passes=verify -S --write-experimental-debuginfo=false \
-; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg
;; Test also that the new flag is independent of the flag that enables use of
;; these non-instruction debug info during LLVM passes.
; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=false < %s \
-; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg
; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=true < %s \
-; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg --implicit-check-not=#dbg
; CHECK: @f(i32 %[[VAL_A:[0-9a-zA-Z]+]])
; CHECK-NEXT: entry:
>From 2e929cba70f5ea1ec2d7baac2790924771f3643a Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Wed, 28 Feb 2024 09:18:25 +0000
Subject: [PATCH 05/10] Parser fixes for DPLabel
---
llvm/include/llvm/AsmParser/LLParser.h | 2 +-
.../include/llvm/IR/DebugProgramInstruction.h | 9 +++
llvm/lib/AsmParser/LLLexer.cpp | 1 +
llvm/lib/AsmParser/LLParser.cpp | 69 +++++++++++++------
llvm/lib/IR/DebugProgramInstruction.cpp | 14 +++-
llvm/lib/IR/Verifier.cpp | 1 +
.../roundtrip-non-instruction-debug-info.ll | 9 ++-
7 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 086f06e15c8627..e5e1ade8b38b36 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -576,7 +576,7 @@ namespace llvm {
bool parseMDNodeTail(MDNode *&N);
bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
bool parseMetadataAttachment(unsigned &Kind, MDNode *&MD);
- bool parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS);
+ bool parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS);
bool parseInstructionMetadata(Instruction &Inst);
bool parseGlobalObjectMetadataAttachment(GlobalObject &GO);
bool parseOptionalFunctionMetadata(Function &F);
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index 33fff815d474f8..4253f549b5697b 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -223,9 +223,18 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) {
class DPLabel : public DbgRecord {
DbgRecordParamRef<DILabel> Label;
+ /// This constructor intentionally left private, so that it is only called via
+ /// "createUnresolvedDPLabel", which clearly expresses that it is for parsing
+ /// only.
+ DPLabel(MDNode *Label, MDNode *DL);
public:
DPLabel(DILabel *Label, DebugLoc DL);
+ /// For use during parsing; creates a DPLabel from as-of-yet unresolved
+ /// MDNodes. Trying to access the resulting DPLabel's fields before they are
+ /// resolved, or if they resolve to the wrong type, will result in a crash.
+ static DPLabel *createUnresolvedDPLabel(MDNode *Label, MDNode *DL);
+
DPLabel *clone() const;
void print(raw_ostream &O, bool IsForDebug = false) const;
void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 632bc404dce0bb..02f64fcfac4f0c 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -938,6 +938,7 @@ lltok::Kind LLLexer::LexIdentifier() {
DBGRECORDTYPEKEYWORD(value);
DBGRECORDTYPEKEYWORD(declare);
DBGRECORDTYPEKEYWORD(assign);
+ DBGRECORDTYPEKEYWORD(label);
#undef DBGRECORDTYPEKEYWORD
if (Keyword.starts_with("DIFlag")) {
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 1556103e4ba598..32dd96b78403f2 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6422,7 +6422,11 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// Parse the instructions and debug values in this block until we get a
// terminator.
Instruction *Inst;
- SmallVector<std::unique_ptr<DPValue>> TrailingDPValues;
+ auto DeleteDbgRecord = [](DbgRecord *DR) {
+ DR->deleteRecord();
+ };
+ using DbgRecordPtr = std::unique_ptr<DbgRecord, decltype(DeleteDbgRecord)>;
+ SmallVector<DbgRecordPtr> TrailingDbgRecord;
do {
// Handle debug records first - there should always be an instruction
// following the debug records, i.e. they cannot appear after the block
@@ -6436,10 +6440,10 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
if (!M->IsNewDbgInfoFormat)
M->convertToNewDbgValues();
- DPValue *DPV;
- if (parseDebugProgramValue(DPV, PFS))
+ DbgRecord *DR;
+ if (parseDebugRecord(DR, PFS))
return true;
- TrailingDPValues.emplace_back(DPV);
+ TrailingDbgRecord.emplace_back(DR, DeleteDbgRecord);
}
// This instruction may have three possibilities for a name: a) none
@@ -6488,35 +6492,58 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
return true;
// Attach any preceding debug values to this instruction.
- for (std::unique_ptr<DPValue> &DPV : TrailingDPValues)
- BB->insertDPValueBefore(DPV.release(), Inst->getIterator());
- TrailingDPValues.clear();
+ for (DbgRecordPtr &DR : TrailingDbgRecord)
+ BB->insertDPValueBefore(DR.release(), Inst->getIterator());
+ TrailingDbgRecord.clear();
} while (!Inst->isTerminator());
- assert(TrailingDPValues.empty() &&
+ assert(TrailingDbgRecord.empty() &&
"All debug values should have been attached to an instruction.");
return false;
}
-/// parseDebugProgramValue
+/// parseDebugRecord
+/// ::= #dbg_label '(' MDNode ')'
/// ::= #dbg_type '(' Metadata ',' MDNode ',' Metadata ','
/// (MDNode ',' Metadata ',' Metadata ',')? MDNode ')'
-bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
+bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
+ using RecordKind = DbgRecord::Kind;
using LocType = DPValue::LocationType;
LocTy DPVLoc = Lex.getLoc();
if (Lex.getKind() != lltok::DbgRecordType)
return error(DPVLoc, "expected debug record type here");
- auto Type = StringSwitch<LocType>(Lex.getStrVal())
+ RecordKind RecordType = StringSwitch<RecordKind>(Lex.getStrVal())
+ .Case("declare", RecordKind::ValueKind)
+ .Case("value", RecordKind::ValueKind)
+ .Case("assign", RecordKind::ValueKind)
+ .Case("label", RecordKind::LabelKind);
+
+ // Parsing labels is trivial; parse here and early exit, otherwise go into the
+ // full DPValue processing stage.
+ if (RecordType == RecordKind::LabelKind) {
+ Lex.Lex();
+ if (parseToken(lltok::lparen, "Expected '(' here"))
+ return true;
+ MDNode *Label;
+ if (parseMDNode(Label))
+ return true;
+ if (parseToken(lltok::comma, "Expected ',' here"))
+ return true;
+ MDNode *DbgLoc;
+ if (parseMDNode(DbgLoc))
+ return true;
+ if (parseToken(lltok::rparen, "Expected ')' here"))
+ return true;
+ DR = DPLabel::createUnresolvedDPLabel(Label, DbgLoc);
+ return false;
+ }
+
+ LocType ValueType = StringSwitch<LocType>(Lex.getStrVal())
.Case("declare", LocType::Declare)
.Case("value", LocType::Value)
- .Case("assign", LocType::Assign)
- .Default(LocType::End);
- // If the file contained an invalid debug record type then parsing should fail
- // above; the assert here should only fire if the Lexer gives us an invalid
- // value.
- assert(Type != LocType::End &&
- "Lexer returned an invalid DbgRecordType string.");
+ .Case("assign", LocType::Assign);
+
Lex.Lex();
if (parseToken(lltok::lparen, "Expected '(' here"))
return true;
@@ -6549,7 +6576,7 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
MDNode *AssignID = nullptr;
Metadata *AddressLocation = nullptr;
Metadata *AddressExpression = nullptr;
- if (Type == LocType::Assign) {
+ if (ValueType == LocType::Assign) {
// Parse DIAssignID.
if (parseMDNode(AssignID))
return true;
@@ -6579,8 +6606,8 @@ bool LLParser::parseDebugProgramValue(DPValue *&DPV, PerFunctionState &PFS) {
if (parseToken(lltok::rparen, "Expected ')' here"))
return true;
- DPV = DPValue::createUnresolvedDPValue(
- Type, ValLocMD, Variable, cast<DIExpression>(Expression), AssignID,
+ DR = DPValue::createUnresolvedDPValue(
+ ValueType, ValLocMD, Variable, cast<DIExpression>(Expression), AssignID,
AddressLocation, cast_or_null<DIExpression>(AddressExpression), DebugLoc);
return false;
}
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index 25cd82fb91f8c4..6ac20b03882036 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -138,16 +138,26 @@ DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
llvm_unreachable("unsupported DbgRecord kind");
}
+
+DPLabel::DPLabel(MDNode *Label, MDNode *DL)
+ : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {
+ assert(Label && "Unexpected nullptr");
+ assert(isa<DILabel>(Label) || Label->isTemporary() && "Label type must be or resolve to a DILabel");
+}
DPLabel::DPLabel(DILabel *Label, DebugLoc DL)
: DbgRecord(LabelKind, DL), Label(Label) {
assert(Label && "Unexpected nullptr");
}
+DPLabel *DPLabel::createUnresolvedDPLabel(MDNode *Label, MDNode *DL) {
+ return new DPLabel(Label, DL);
+}
+
DPValue::DPValue(DPValue::LocationType Type, Metadata *Val, MDNode *Variable,
MDNode *Expression, MDNode *AssignID, Metadata *Address,
MDNode *AddressExpression, MDNode *DI)
- : DebugValueUser({Val, Address, AssignID}), Variable(Variable),
- Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
+ : DbgRecord(ValueKind, DebugLoc(DI)), DebugValueUser({Val, Address, AssignID}), Variable(Variable),
+ Expression(Expression), AddressExpression(AddressExpression),
Type(Type) {}
DPValue *DPValue::createUnresolvedDPValue(DPValue::LocationType Type,
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 027c6ccd1ab304..eea98946d6feb4 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -684,6 +684,7 @@ void Verifier::visitDbgRecords(Instruction &I) {
&I);
CheckDI(!isa<PHINode>(&I) || !I.hasDbgValues(),
"PHI Node must not have any attached DbgRecords", &I);
+ //for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
for (DbgRecord &DR : I.getDbgValueRange()) {
CheckDI(DR.getMarker() == I.DbgMarker, "DbgRecord had invalid DbgMarker",
&I, &DR);
diff --git a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
index 434864270f660d..b15b76d1690c41 100644
--- a/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
+++ b/llvm/test/DebugInfo/roundtrip-non-instruction-debug-info.ll
@@ -28,6 +28,8 @@
; CHECK-NEXT: {{^}} %[[VAL_ADD:[0-9a-zA-Z]+]] = add i32 %[[VAL_A]], 5
; OLDDBG-NEXT: call void @llvm.dbg.value(metadata !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), metadata ![[VAR_A]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg ![[LOC_3:[0-9]+]]
; NEWDBG-NEXT: {{^}} #dbg_value(!DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]])
+; OLDDBG-NEXT: call void @llvm.dbg.label(metadata ![[LABEL_ID:[0-9]+]]), !dbg ![[LOC_3]]
+; NEWDBG-NEXT: {{^}} #dbg_label(![[LABEL_ID:[0-9]+]], ![[LOC_3]])
; CHECK-NEXT: {{^}} store i32 %[[VAL_ADD]]{{.+}}, !DIAssignID ![[ASSIGNID:[0-9]+]]
; OLDDBG-NEXT: call void @llvm.dbg.assign(metadata i32 %[[VAL_ADD]], metadata ![[VAR_B]], metadata !DIExpression(), metadata ![[ASSIGNID]], metadata ptr %[[VAL_B]], metadata !DIExpression()), !dbg ![[LOC_4:[0-9]+]]
; NEWDBG-NEXT: {{^}} #dbg_assign(i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]])
@@ -36,6 +38,7 @@
; OLDDBG-DAG: declare void @llvm.dbg.value
; OLDDBG-DAG: declare void @llvm.dbg.declare
; OLDDBG-DAG: declare void @llvm.dbg.assign
+; OLDDBG-DAG: declare void @llvm.dbg.label
; CHECK-DAG: llvm.dbg.cu
; CHECK-DAG: ![[VAR_A]] = !DILocalVariable(name: "a"
@@ -44,6 +47,7 @@
; CHECK-DAG: ![[LOC_2]] = !DILocation(line: 3, column: 20
; CHECK-DAG: ![[LOC_3]] = !DILocation(line: 3, column: 25
; CHECK-DAG: ![[LOC_4]] = !DILocation(line: 3, column: 30
+; CHECK-DAG: ![[LABEL_ID]] = !DILabel(
define dso_local i32 @f(i32 %a) !dbg !7 {
entry:
@@ -52,6 +56,7 @@ entry:
call void @llvm.dbg.declare(metadata ptr %b, metadata !21, metadata !DIExpression()), !dbg !31
%add = add i32 %a, 5, !dbg !31
call void @llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %add), metadata !20, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !32
+ call void @llvm.dbg.label(metadata !50), !dbg !32
store i32 %add, ptr %b, !dbg !32, !DIAssignID !40
call void @llvm.dbg.assign(metadata i32 %add, metadata !21, metadata !DIExpression(), metadata !40, metadata ptr %b, metadata !DIExpression()), !dbg !33
ret i32 %add, !dbg !33
@@ -61,6 +66,7 @@ entry:
declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @llvm.dbg.declare(metadata, metadata, metadata)
declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+declare void @llvm.dbg.label(metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
@@ -84,4 +90,5 @@ declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata,
!31 = !DILocation(line: 3, column: 20, scope: !7)
!32 = !DILocation(line: 3, column: 25, scope: !7)
!33 = !DILocation(line: 3, column: 30, scope: !7)
-!40 = distinct !DIAssignID()
\ No newline at end of file
+!40 = distinct !DIAssignID()
+!50 = !DILabel(scope: !7, name: "label", file: !1, line: 3)
\ No newline at end of file
>From f1903e0b302cd208dee9e94389b321b9c6ad6667 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Wed, 28 Feb 2024 18:09:38 +0000
Subject: [PATCH 06/10] Parser fixes
---
llvm/lib/AsmParser/LLParser.cpp | 16 ++++++----------
llvm/lib/IR/DebugProgramInstruction.cpp | 7 +++----
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 32dd96b78403f2..379c5a42667f37 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6564,18 +6564,16 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
// Parse Expression field.
LocTy ExprLoc = Lex.getLoc();
- Metadata *Expression;
- if (parseMetadata(Expression, &PFS))
+ MDNode *Expression;
+ if (parseMDNode(Expression))
return true;
- if (!isa<DIExpression>(Expression))
- return error(ExprLoc, "expected valid inline DIExpression here");
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
// Parse additional fields for #dbg_assign.
MDNode *AssignID = nullptr;
Metadata *AddressLocation = nullptr;
- Metadata *AddressExpression = nullptr;
+ MDNode *AddressExpression = nullptr;
if (ValueType == LocType::Assign) {
// Parse DIAssignID.
if (parseMDNode(AssignID))
@@ -6591,10 +6589,8 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
// Parse address DIExpression.
LocTy AddressExprLoc = Lex.getLoc();
- if (parseMetadata(AddressExpression, &PFS))
+ if (parseMDNode(AddressExpression))
return true;
- if (!isa<DIExpression>(AddressExpression))
- return error(AddressExprLoc, "expected valid inline DIExpression here");
if (parseToken(lltok::comma, "Expected ',' here"))
return true;
}
@@ -6607,8 +6603,8 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
if (parseToken(lltok::rparen, "Expected ')' here"))
return true;
DR = DPValue::createUnresolvedDPValue(
- ValueType, ValLocMD, Variable, cast<DIExpression>(Expression), AssignID,
- AddressLocation, cast_or_null<DIExpression>(AddressExpression), DebugLoc);
+ ValueType, ValLocMD, Variable, Expression, AssignID,
+ AddressLocation, AddressExpression, DebugLoc);
return false;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index 6ac20b03882036..dbeaa674106098 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -142,7 +142,7 @@ DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
DPLabel::DPLabel(MDNode *Label, MDNode *DL)
: DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {
assert(Label && "Unexpected nullptr");
- assert(isa<DILabel>(Label) || Label->isTemporary() && "Label type must be or resolve to a DILabel");
+ assert((isa<DILabel>(Label) || Label->isTemporary()) && "Label type must be or resolve to a DILabel");
}
DPLabel::DPLabel(DILabel *Label, DebugLoc DL)
: DbgRecord(LabelKind, DL), Label(Label) {
@@ -156,9 +156,8 @@ DPLabel *DPLabel::createUnresolvedDPLabel(MDNode *Label, MDNode *DL) {
DPValue::DPValue(DPValue::LocationType Type, Metadata *Val, MDNode *Variable,
MDNode *Expression, MDNode *AssignID, Metadata *Address,
MDNode *AddressExpression, MDNode *DI)
- : DbgRecord(ValueKind, DebugLoc(DI)), DebugValueUser({Val, Address, AssignID}), Variable(Variable),
- Expression(Expression), AddressExpression(AddressExpression),
- Type(Type) {}
+ : DbgRecord(ValueKind, DebugLoc(DI)), DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),
+ Expression(Expression), AddressExpression(AddressExpression) {}
DPValue *DPValue::createUnresolvedDPValue(DPValue::LocationType Type,
Metadata *Val, MDNode *Variable,
>From 3bee3661f0d95673bd026e698c34b41bf9cb877d Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Wed, 28 Feb 2024 18:27:52 +0000
Subject: [PATCH 07/10] Unused variables
---
llvm/lib/AsmParser/LLParser.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 379c5a42667f37..02c32cff3c53a7 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6563,7 +6563,6 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
return true;
// Parse Expression field.
- LocTy ExprLoc = Lex.getLoc();
MDNode *Expression;
if (parseMDNode(Expression))
return true;
@@ -6588,7 +6587,6 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
return true;
// Parse address DIExpression.
- LocTy AddressExprLoc = Lex.getLoc();
if (parseMDNode(AddressExpression))
return true;
if (parseToken(lltok::comma, "Expected ',' here"))
>From ea2a9245ef94dd5b14fbb3237888c1875a7aa3fb Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Wed, 28 Feb 2024 18:20:43 +0000
Subject: [PATCH 08/10] Add tests (requires parsing)
---
llvm/test/Verifier/RemoveDI/blockbyref.ll | 18 ++++++
.../Verifier/RemoveDI/dbg-invalid-vector.ll | 35 +++++++++++
.../RemoveDI/di-subroutine-localvar.ll | 41 ++++++++++++
.../diexpression-entry-value-llvm-ir.ll | 34 ++++++++++
.../test/Verifier/RemoveDI/fnarg-debuginfo.ll | 26 ++++++++
llvm/test/Verifier/RemoveDI/fnarg-nodebug.ll | 58 +++++++++++++++++
.../RemoveDI/invalid-disubrange-count-node.ll | 36 +++++++++++
.../RemoveDI/llvm.dbg.declare-address.ll | 16 +++++
.../RemoveDI/llvm.dbg.declare-expression.ll | 16 +++++
.../RemoveDI/llvm.dbg.declare-variable.ll | 17 +++++
.../llvm.dbg.intrinsic-dbg-attachment.ll | 55 ++++++++++++++++
.../RemoveDI/llvm.dbg.value-expression.ll | 16 +++++
.../Verifier/RemoveDI/llvm.dbg.value-value.ll | 17 +++++
.../RemoveDI/llvm.dbg.value-variable.ll | 17 +++++
llvm/test/Verifier/RemoveDI/set1.ll | 62 +++++++++++++++++++
15 files changed, 464 insertions(+)
create mode 100644 llvm/test/Verifier/RemoveDI/blockbyref.ll
create mode 100644 llvm/test/Verifier/RemoveDI/dbg-invalid-vector.ll
create mode 100644 llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll
create mode 100644 llvm/test/Verifier/RemoveDI/diexpression-entry-value-llvm-ir.ll
create mode 100644 llvm/test/Verifier/RemoveDI/fnarg-debuginfo.ll
create mode 100644 llvm/test/Verifier/RemoveDI/fnarg-nodebug.ll
create mode 100644 llvm/test/Verifier/RemoveDI/invalid-disubrange-count-node.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.declare-address.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.declare-expression.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.declare-variable.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.intrinsic-dbg-attachment.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.value-expression.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.value-value.ll
create mode 100644 llvm/test/Verifier/RemoveDI/llvm.dbg.value-variable.ll
create mode 100644 llvm/test/Verifier/RemoveDI/set1.ll
diff --git a/llvm/test/Verifier/RemoveDI/blockbyref.ll b/llvm/test/Verifier/RemoveDI/blockbyref.ll
new file mode 100644
index 00000000000000..86321a6ae78e80
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/blockbyref.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s
+
+; CHECK: DIBlockByRefStruct on DICompositeType is no longer supported
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo() {
+entry:
+ %s = alloca i32
+ #dbg_declare(ptr %s, !2, !DIExpression(), !DILocation(scope: !1))
+ ret void
+}
+
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
+!2 = !DILocalVariable(scope: !1, type: !3)
+!3 = !DICompositeType(tag: DW_TAG_structure_type, flags: DIFlagReservedBit4)
diff --git a/llvm/test/Verifier/RemoveDI/dbg-invalid-vector.ll b/llvm/test/Verifier/RemoveDI/dbg-invalid-vector.ll
new file mode 100644
index 00000000000000..0832c361c3080e
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/dbg-invalid-vector.ll
@@ -0,0 +1,35 @@
+; RUN: opt -passes=verify -disable-output <%s 2>&1 | FileCheck %s
+;
+; This test creates an invalid vector by defining multiple elements for the
+; vector's DICompositeType definition. A vector should only have one element
+; in its DICompositeType 'elements' array.
+;
+; CHECK: invalid vector
+
+ at f.foo = private unnamed_addr constant <6 x float> zeroinitializer, align 32
+
+define void @f() {
+ %1 = alloca <6 x float>, align 32
+ #dbg_declare(ptr %1, !10, !DIExpression(), !18)
+ ret void
+}
+
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "test.c", directory: "/dbg/info")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null}
+!10 = !DILocalVariable(name: "foo", scope: !7, file: !1, line: 4, type: !12)
+!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 256, flags: DIFlagVector, elements: !14)
+!13 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!14 = !{!15, !19}
+!15 = !DISubrange(count: 6)
+!18 = !DILocation(line: 4, column: 48, scope: !7)
+!19 = !DISubrange(count: 42)
diff --git a/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll b/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll
new file mode 100644
index 00000000000000..14e58883989968
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/di-subroutine-localvar.ll
@@ -0,0 +1,41 @@
+; RUN: opt %s -passes=verify 2>&1 | FileCheck %s
+; CHECK: invalid type
+; CHECK: !20 = !DILocalVariable(name: "f", scope: !21, file: !13, line: 970, type: !14)
+; CHECK: !14 = !DISubroutineType(types: !15)
+
+
+%timespec.0.1.2.3.0.1.2 = type { i64, i64 }
+define internal i64 @init_vdso_clock_gettime(i32, ptr nonnull) unnamed_addr !dbg !142 {
+ #dbg_value(ptr null, !162, !DIExpression(), !167)
+ ret i64 -38, !dbg !168
+}
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!1}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "zig 0.3.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !76)
+!2 = !DIFile(filename: "test", directory: ".")
+!3 = !{!4}
+!4 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "Arch", scope: !5, file: !5, line: 44, baseType: !6, size: 8, align: 8, elements: !7)
+!5 = !DIFile(filename: "builtin.zig", directory: "/home/andy/.local/share/zig/stage1/builtin/ugMGxVES9OkDAffv3xhJS3KQVy0Wm1xPM3Bc6x4MBuup5aetdi5pVTrGRG2aDAn0")
+!6 = !DIBasicType(name: "u7", size: 8, encoding: DW_ATE_unsigned)
+!7 = !{!8}
+!8 = !DIEnumerator(name: "armv8_5a", value: 0)
+!76 = !{!77}
+!77 = !DIGlobalVariableExpression(var: !78, expr: !DIExpression())
+!78 = distinct !DIGlobalVariable(name: "arch", linkageName: "arch", scope: !5, file: !5, line: 437, type: !4, isLocal: true, isDefinition: true)
+!81 = !DIFile(filename: "index.zig", directory: "/store/dev/zig/build-llvm8-debug/lib/zig/std/os/linux")
+!142 = distinct !DISubprogram(name: "init_vdso_clock_gettime", scope: !81, file: !81, line: 968, type: !143, scopeLine: 968, flags: DIFlagStaticMember, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !1, retainedNodes: !153)
+!143 = !DISubroutineType(types: !144)
+!144 = !{!145}
+!145 = !DIBasicType(name: "usize", size: 64, encoding: DW_ATE_unsigned)
+!146 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
+!153 = !{!154}
+!154 = !DILocalVariable(name: "clk", arg: 1, scope: !142, file: !81, line: 968, type: !146)
+!162 = !DILocalVariable(name: "f", scope: !163, file: !81, line: 970, type: !143)
+!163 = distinct !DILexicalBlock(scope: !164, file: !81, line: 969, column: 5)
+!164 = distinct !DILexicalBlock(scope: !165, file: !81, line: 968, column: 66)
+!165 = distinct !DILexicalBlock(scope: !166, file: !81, line: 968, column: 45)
+!166 = distinct !DILexicalBlock(scope: !142, file: !81, line: 968, column: 35)
+!167 = !DILocation(line: 970, column: 5, scope: !163)
+!168 = !DILocation(line: 972, column: 28, scope: !169)
+!169 = distinct !DILexicalBlock(scope: !163, file: !81, line: 970, column: 5)
diff --git a/llvm/test/Verifier/RemoveDI/diexpression-entry-value-llvm-ir.ll b/llvm/test/Verifier/RemoveDI/diexpression-entry-value-llvm-ir.ll
new file mode 100644
index 00000000000000..881ec4a86fb644
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/diexpression-entry-value-llvm-ir.ll
@@ -0,0 +1,34 @@
+; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s
+
+; CHECK-NOT: #dbg_value
+; CHECK: Entry values are only allowed in MIR unless they target a swiftasync Argument
+; CHECK: #dbg_value(i32 %param, !{{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1)
+; CHECK-NOT: #dbg_value
+; CHECK-NOT: Entry values are only allowed
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %param, ptr swiftasync %ok_param) !dbg !4 {
+entry:
+ #dbg_value(i32 %param, !8, !DIExpression(DW_OP_LLVM_entry_value, 1), !9)
+ #dbg_value(ptr %ok_param, !8, !DIExpression(DW_OP_LLVM_entry_value, 1), !9)
+ #dbg_value(ptr poison, !8, !DIExpression(DW_OP_LLVM_entry_value, 1), !9)
+ #dbg_value(ptr undef, !8, !DIExpression(DW_OP_LLVM_entry_value, 1), !9)
+ ret void
+}
+
+
+attributes #0 = { nounwind readnone speculatable willreturn }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug)
+!1 = !DIFile(filename: "a.c", directory: "/")
+!2 = !{i32 2, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, type: !5, unit: !0)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null, !7}
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !DILocalVariable(name: "param", arg: 1, scope: !4, file: !1, type: !7)
+!9 = !DILocation(line: 0, scope: !4)
diff --git a/llvm/test/Verifier/RemoveDI/fnarg-debuginfo.ll b/llvm/test/Verifier/RemoveDI/fnarg-debuginfo.ll
new file mode 100644
index 00000000000000..db1a9a8ba18945
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/fnarg-debuginfo.ll
@@ -0,0 +1,26 @@
+; RUN: llvm-as -disable-output < %s -o /dev/null 2>&1 | FileCheck %s
+
+
+define void @foo() !dbg !2 {
+entry:
+ %a = alloca i32
+ ; CHECK: conflicting debug info for argument
+ #dbg_value(i32 0, !3, !DIExpression(), !6)
+ #dbg_declare(ptr %a, !4, !DIExpression(), !6)
+ ret void, !dbg !6
+}
+
+; CHECK: warning: ignoring invalid debug info
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", emissionKind: FullDebug)
+!1 = !DIFile(filename: "x.c", directory: "/")
+!2 = distinct !DISubprogram(name: "foo", scope: !0, isDefinition: true, unit: !0)
+!3 = !DILocalVariable(name: "a", arg: 1, scope: !2, file: !1, line: 1, type: !5)
+!4 = !DILocalVariable(name: "b", arg: 1, scope: !2, file: !1, line: 1, type: !5)
+!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!6 = !DILocation(line: 1, scope: !2)
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 1, !"Debug Info Version", i32 3}
diff --git a/llvm/test/Verifier/RemoveDI/fnarg-nodebug.ll b/llvm/test/Verifier/RemoveDI/fnarg-nodebug.ll
new file mode 100644
index 00000000000000..f5526030278eb9
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/fnarg-nodebug.ll
@@ -0,0 +1,58 @@
+; RUN: llvm-as < %s -o %t
+; RUN: llvm-dis < %t -o - | FileCheck %s
+; Created at -O1 from:
+; int sink(int);
+; __attribute__((always_inline)) int f(int i) { return sink(i); }
+; __attribute__((always_inline)) int g(int j) { return sink(j); }
+; __attribute__((nodebug)) int nodebug(int k) { return f(k)+g(k); }
+source_filename = "t.c"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+declare i32 @sink(i32) local_unnamed_addr
+
+define i32 @nodebug(i32 %k) local_unnamed_addr #2 {
+entry:
+; This should not set off the FnArg Verifier. The two variables are in differrent scopes.
+ #dbg_value(i32 %k, !12, !13, !14)
+ %call.k = tail call i32 @sink(i32 %k) #4, !dbg !15
+ #dbg_value(i32 %k, !19, !13, !20)
+ %call.k3 = tail call i32 @sink(i32 %k) #4, !dbg !21
+ %add = add nsw i32 %call.k3, %call.k
+ ret i32 %add
+}
+
+; Function Attrs: nounwind readnone
+
+attributes #2 = { nounwind ssp uwtable }
+attributes #3 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.0 (trunk 297153) (llvm/trunk 297155)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "t.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"PIC Level", i32 2}
+!6 = !{!"clang version 5.0.0 (trunk 297153) (llvm/trunk 297155)"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+; CHECK: !DILocalVariable(name: "i", arg: 1
+!12 = !DILocalVariable(name: "i", arg: 1, scope: !7, file: !1, line: 2, type: !10)
+!13 = !DIExpression()
+!14 = !DILocation(line: 2, column: 42, scope: !7)
+!15 = !DILocation(line: 2, column: 54, scope: !7)
+!16 = !DILocation(line: 2, column: 47, scope: !7)
+!17 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !18)
+!18 = !{!19}
+; CHECK: !DILocalVariable(name: "j", arg: 1
+!19 = !DILocalVariable(name: "j", arg: 1, scope: !17, file: !1, line: 3, type: !10)
+!20 = !DILocation(line: 3, column: 42, scope: !17)
+!21 = !DILocation(line: 3, column: 54, scope: !17)
+!22 = !DILocation(line: 3, column: 47, scope: !17)
diff --git a/llvm/test/Verifier/RemoveDI/invalid-disubrange-count-node.ll b/llvm/test/Verifier/RemoveDI/invalid-disubrange-count-node.ll
new file mode 100644
index 00000000000000..f36cee5946e473
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/invalid-disubrange-count-node.ll
@@ -0,0 +1,36 @@
+; RUN: llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+define void @foo(i32 %n) {
+entry:
+ %0 = zext i32 %n to i64
+ %vla = alloca i32, i64 %0, align 16
+ #dbg_declare(ptr %vla, !19, !DIExpression(), !18)
+ ret void
+}
+
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "vla.c", directory: "/path/to")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 5.0.1"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 20, type: !8, isLocal: false, isDefinition: true, scopeLine: 20, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!16, !19}
+!12 = !DIExpression()
+!16 = !DILocalVariable(name: "vla_expr", scope: !7, file: !1, line: 21, type: !17)
+!17 = !DIBasicType(name: "long unsigned int", size: 64, encoding: DW_ATE_unsigned)
+!18 = !DILocation(line: 21, column: 7, scope: !7)
+!19 = !DILocalVariable(name: "vla", scope: !7, file: !1, line: 21, type: !20)
+!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, align: 32, elements: !21)
+!21 = !{!22}
+; CHECK: Count must be signed constant or DIVariable or DIExpression
+!22 = !DISubrange(count: !17)
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-address.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-address.ll
new file mode 100644
index 00000000000000..9d400b892ce8c1
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-address.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record address/value
+; CHECK-NEXT: #dbg_declare({{.*}})
+; CHECK-NEXT: !""
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %a) {
+entry:
+ %s = alloca i32
+ #dbg_declare(!"", !DILocalVariable(scope: !1), !DIExpression(), !DILocation(scope: !1))
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-expression.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-expression.ll
new file mode 100644
index 00000000000000..b52c15cb3f8816
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-expression.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record expression
+; CHECK-NEXT: #dbg_declare({{.*}})
+; CHECK-NEXT: !{}
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %a) {
+entry:
+ %s = alloca i32
+ #dbg_declare(ptr %s, !DILocalVariable(scope: !1), !{}, !DILocation(scope: !1))
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-variable.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-variable.ll
new file mode 100644
index 00000000000000..db2b0e0a54e2bd
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.declare-variable.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record variable
+; CHECK-NEXT: #dbg_declare({{.*}})
+; CHECK-NEXT: !{}
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %a) {
+entry:
+ %s = alloca i32
+ #dbg_declare(ptr %s, !{}, !DIExpression(), !DILocation(scope: !1))
+ ret void
+}
+
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.intrinsic-dbg-attachment.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.intrinsic-dbg-attachment.ll
new file mode 100644
index 00000000000000..226324036a5bbd
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.intrinsic-dbg-attachment.ll
@@ -0,0 +1,55 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+define void @foo() {
+entry:
+ #dbg_value(
+ ptr undef,
+ !DILocalVariable(scope: !1),
+ !DIExpression(),
+ !{})
+; CHECK-LABEL: invalid #dbg record location
+; CHECK-NEXT: #dbg_value({{.*}})
+
+ #dbg_declare(
+ ptr undef,
+ !DILocalVariable(scope: !1),
+ !DIExpression(),
+ !{})
+; CHECK-LABEL: invalid #dbg record location
+; CHECK-NEXT: #dbg_declare({{.*}})
+
+ #dbg_value(
+ ptr undef,
+ !DILocalVariable(scope: !1),
+ !DIExpression(),
+ !DILocation(scope: !2))
+; CHECK-LABEL: mismatched subprogram between #dbg record variable and DILocation
+; CHECK-NEXT: #dbg_value({{[^,]+}}, ![[VAR:[0-9]+]], {{[^,]+}}, ![[LOC:[0-9]+]]
+; CHECK-NEXT: label %entry
+; CHECK-NEXT: ptr @foo
+; CHECK-NEXT: ![[VAR]] = !DILocalVariable({{.*}}scope: ![[VARSP:[0-9]+]]
+; CHECK-NEXT: ![[VARSP]] = distinct !DISubprogram(
+; CHECK-NEXT: ![[LOC]] = !DILocation({{.*}}scope: ![[LOCSP:[0-9]+]]
+; CHECK-NEXT: ![[LOCSP]] = distinct !DISubprogram(
+
+ #dbg_declare(
+ ptr undef,
+ !DILocalVariable(scope: !1),
+ !DIExpression(),
+ !DILocation(scope: !2))
+; CHECK-LABEL: mismatched subprogram between #dbg record variable and DILocation
+; CHECK-NEXT: #dbg_declare({{[^,]+}}, ![[VAR:[0-9]+]], {{.*[^,]+}}, ![[LOC:[0-9]+]]
+; CHECK-NEXT: label %entry
+; CHECK-NEXT: ptr @foo
+; CHECK-NEXT: ![[VAR]] = !DILocalVariable({{.*}}scope: ![[VARSP:[0-9]+]]
+; CHECK-NEXT: ![[VARSP]] = distinct !DISubprogram(
+; CHECK-NEXT: ![[LOC]] = !DILocation({{.*}}scope: ![[LOCSP:[0-9]+]]
+; CHECK-NEXT: ![[LOCSP]] = distinct !DISubprogram(
+
+ ret void
+}
+
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram(name: "foo")
+!2 = distinct !DISubprogram(name: "bar")
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.value-expression.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.value-expression.ll
new file mode 100644
index 00000000000000..cbd93c1ce6a4d6
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.value-expression.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record expression
+; CHECK-NEXT: #dbg_value({{.*}})
+; CHECK-NEXT: !{}
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %a) {
+entry:
+ %s = alloca i32
+ #dbg_value(ptr %s, !DILocalVariable(scope: !1), !{}, !DILocation(scope: !1))
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.value-value.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.value-value.ll
new file mode 100644
index 00000000000000..b6fcde250526be
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.value-value.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record address/value
+; CHECK-NEXT: #dbg_value({{.*}})
+; CHECK-NEXT: !""
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %a) {
+entry:
+ %s = alloca i32
+ #dbg_value(!"", !DILocalVariable(scope: !1), !DIExpression(), !DILocation(scope: !1))
+ ret void
+}
+
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
diff --git a/llvm/test/Verifier/RemoveDI/llvm.dbg.value-variable.ll b/llvm/test/Verifier/RemoveDI/llvm.dbg.value-variable.ll
new file mode 100644
index 00000000000000..0a5fe79453d721
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/llvm.dbg.value-variable.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+; CHECK: invalid #dbg record variable
+; CHECK-NEXT: #dbg_value({{.*}})
+; CHECK-NEXT: !{}
+; CHECK: warning: ignoring invalid debug info
+
+define void @foo(i32 %a) {
+entry:
+ %s = alloca i32
+ #dbg_value(ptr %s, !{}, !DIExpression(), !DILocation(scope: !1))
+ ret void
+}
+
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DISubprogram()
diff --git a/llvm/test/Verifier/RemoveDI/set1.ll b/llvm/test/Verifier/RemoveDI/set1.ll
new file mode 100644
index 00000000000000..d54ba8876c366c
--- /dev/null
+++ b/llvm/test/Verifier/RemoveDI/set1.ll
@@ -0,0 +1,62 @@
+; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
+
+define void @Main__Test() #0 !dbg !17 {
+entry:
+ %as = alloca i64, align 8
+ %bs = alloca i64, align 8
+ br label %second, !dbg !21
+
+second: ; preds = %entry
+ #dbg_declare(ptr %as, !22, !DIExpression(), !25)
+ #dbg_declare(ptr %bs, !26, !DIExpression(), !25)
+ store i64 36028797018972298, ptr %as, align 8, !dbg !28
+ store i64 85, ptr %bs, align 8, !dbg !29
+ ret void, !dbg !21
+}
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+
+!llvm.ident = !{!0}
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!14, !15, !16}
+
+!0 = !{!"versions- cm3: d5.10.0 llvm: 12.0"}
+!1 = distinct !DICompileUnit(language: DW_LANG_Modula3, file: !2, producer: "cm3", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3)
+!2 = !DIFile(filename: "Main.m3", directory: "/home/peter/cm3/settest/src")
+!3 = !{!4}
+!4 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum", scope: !2, file: !2, line: 11, size: 8, align: 8, elements: !5)
+!5 = !{!6, !7, !8, !9, !10, !11, !12, !13}
+!6 = !DIEnumerator(name: "alpha", value: 0)
+!7 = !DIEnumerator(name: "beta", value: 1)
+!8 = !DIEnumerator(name: "gamma", value: 2)
+!9 = !DIEnumerator(name: "delta", value: 3)
+!10 = !DIEnumerator(name: "epsilon", value: 4)
+!11 = !DIEnumerator(name: "theta", value: 5)
+!12 = !DIEnumerator(name: "psi", value: 6)
+!13 = !DIEnumerator(name: "zeta", value: 7)
+!14 = !{i64 2, !"Dwarf Version", i64 4}
+!15 = !{i64 2, !"Debug Info Version", i64 3}
+!16 = !{i64 2, !"wchar_size", i64 2}
+!17 = distinct !DISubprogram(name: "Test", linkageName: "Main__Test", scope: !2, file: !2, line: 11, type: !18, scopeLine: 11, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !20)
+!18 = !DISubroutineType(types: !19)
+!19 = !{null}
+!20 = !{}
+!21 = !DILocation(line: 20, scope: !17)
+!22 = !DILocalVariable(name: "as", scope: !17, file: !2, line: 11, type: !23)
+; CHECK: invalid set base type
+!23 = !DIDerivedType(tag: DW_TAG_set_type, name: "SS", scope: !2, file: !2, line: 11, baseType: !24, size: 64, align: 64)
+!24 = !DIBasicType(name: "SR", size: 8, encoding: DW_ATE_signed)
+!25 = !DILocation(line: 11, scope: !17)
+!26 = !DILocalVariable(name: "bs", scope: !17, file: !2, line: 11, type: !27)
+!27 = !DIDerivedType(tag: DW_TAG_set_type, name: "ST", scope: !2, file: !2, line: 11, baseType: !23, size: 64, align: 64)
+!28 = !DILocation(line: 17, scope: !17)
+!29 = !DILocation(line: 18, scope: !17)
+!30 = distinct !DISubprogram(name: "Main_M3", linkageName: "Main_M3", scope: !2, file: !2, line: 22, type: !31, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !20)
+!31 = !DISubroutineType(types: !32)
+!32 = !{!33, !35}
+!33 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "ADDR", baseType: !34, size: 64, align: 64)
+!34 = !DICompositeType(tag: DW_TAG_class_type, name: "ADDR__HeapObject", scope: !2, file: !2, line: 22, size: 64, align: 64, elements: !19, identifier: "AJWxb1")
+!35 = !DIBasicType(name: "INTEGER", size: 64, encoding: DW_ATE_signed)
+!36 = !DILocation(line: 23, scope: !30)
+!37 = !DILocalVariable(name: "mode", arg: 1, scope: !30, file: !2, line: 22, type: !35)
+!38 = !DILocation(line: 22, scope: !30)
>From b56190db4d35efb9bea180a58d5f95707240c03a Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Fri, 1 Mar 2024 11:11:06 +0000
Subject: [PATCH 09/10] Delete tests for DIExpression validity
---
llvm/test/Assembler/dbg-record-invalid-10.ll | 36 --------------------
llvm/test/Assembler/dbg-record-invalid-11.ll | 35 -------------------
llvm/test/Assembler/dbg-record-invalid-5.ll | 10 +++---
llvm/test/Assembler/dbg-record-invalid-6.ll | 9 +++--
4 files changed, 8 insertions(+), 82 deletions(-)
delete mode 100644 llvm/test/Assembler/dbg-record-invalid-10.ll
delete mode 100644 llvm/test/Assembler/dbg-record-invalid-11.ll
diff --git a/llvm/test/Assembler/dbg-record-invalid-10.ll b/llvm/test/Assembler/dbg-record-invalid-10.ll
deleted file mode 100644
index 72dafcdb97fce4..00000000000000
--- a/llvm/test/Assembler/dbg-record-invalid-10.ll
+++ /dev/null
@@ -1,36 +0,0 @@
-;; Test that we get a parser error when we have a debug record with an
-;; incorrect number of arguments.
-; RUN: not llvm-as < %s 2>&1 | FileCheck %s
-; ModuleID = '<stdin>'
-source_filename = "<stdin>"
-
-define dso_local i32 @f(i32 %a) !dbg !7 {
-entry:
-; CHECK: <stdin>:[[@LINE+1]]:46: error: expected '!' here
- #dbg_value(i32 %a, !12, !DIExpression(), i32 0)
- ret i32 %a, !dbg !18
-}
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5}
-!llvm.ident = !{!6}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
-!1 = !DIFile(filename: "print.c", directory: "/tmp")
-!2 = !{}
-!3 = !{i32 2, !"Dwarf Version", i32 5}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 4}
-!6 = !{!"clang version 18.0.0"}
-!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
-!8 = !DISubroutineType(types: !9)
-!9 = !{!10, !10}
-!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!11 = !{!12, !13}
-!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
-!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
-!14 = !DILocation(line: 3, column: 15, scope: !7)
-!15 = distinct !DIAssignID()
-!16 = !DILocation(line: 3, column: 20, scope: !7)
-!17 = !DILocation(line: 3, column: 25, scope: !7)
-!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-record-invalid-11.ll b/llvm/test/Assembler/dbg-record-invalid-11.ll
deleted file mode 100644
index 5ea588b87668c4..00000000000000
--- a/llvm/test/Assembler/dbg-record-invalid-11.ll
+++ /dev/null
@@ -1,35 +0,0 @@
-;; Test that we get a parser error when a basic block contains only a debug
-;; record.
-; RUN: not llvm-as < %s 2>&1 | FileCheck %s
-; ModuleID = '<stdin>'
-source_filename = "<stdin>"
-
-define dso_local i32 @f(i32 %a) !dbg !7 {
-entry:
- #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
-; CHECK: <stdin>:[[@LINE+1]]:1: error: expected instruction opcode
-}
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5}
-!llvm.ident = !{!6}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
-!1 = !DIFile(filename: "print.c", directory: "/tmp")
-!2 = !{}
-!3 = !{i32 2, !"Dwarf Version", i32 5}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 4}
-!6 = !{!"clang version 18.0.0"}
-!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
-!8 = !DISubroutineType(types: !9)
-!9 = !{!10, !10}
-!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!11 = !{!12, !13}
-!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10)
-!13 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !10)
-!14 = !DILocation(line: 3, column: 15, scope: !7)
-!15 = distinct !DIAssignID()
-!16 = !DILocation(line: 3, column: 20, scope: !7)
-!17 = !DILocation(line: 3, column: 25, scope: !7)
-!18 = !DILocation(line: 3, column: 30, scope: !7)
diff --git a/llvm/test/Assembler/dbg-record-invalid-5.ll b/llvm/test/Assembler/dbg-record-invalid-5.ll
index 2b3e3a763221d3..5ea588b87668c4 100644
--- a/llvm/test/Assembler/dbg-record-invalid-5.ll
+++ b/llvm/test/Assembler/dbg-record-invalid-5.ll
@@ -1,14 +1,13 @@
-;; Test that we get a parser error when we have a debug record that does not use
-;; an inline DIExpression.
+;; Test that we get a parser error when a basic block contains only a debug
+;; record.
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
; ModuleID = '<stdin>'
source_filename = "<stdin>"
define dso_local i32 @f(i32 %a) !dbg !7 {
entry:
-; CHECK: <stdin>:[[@LINE+1]]:29: error: expected valid inline DIExpression here
- #dbg_value(i32 %a, !12, !20, !14)
- ret i32 %a, !dbg !18
+ #dbg_value(!DIArgList(i32 %a), !12, !DIExpression(), !14)
+; CHECK: <stdin>:[[@LINE+1]]:1: error: expected instruction opcode
}
!llvm.dbg.cu = !{!0}
@@ -34,4 +33,3 @@ entry:
!16 = !DILocation(line: 3, column: 20, scope: !7)
!17 = !DILocation(line: 3, column: 25, scope: !7)
!18 = !DILocation(line: 3, column: 30, scope: !7)
-!20 = !DIExpression()
diff --git a/llvm/test/Assembler/dbg-record-invalid-6.ll b/llvm/test/Assembler/dbg-record-invalid-6.ll
index 9aff3c79d79bb5..72dafcdb97fce4 100644
--- a/llvm/test/Assembler/dbg-record-invalid-6.ll
+++ b/llvm/test/Assembler/dbg-record-invalid-6.ll
@@ -1,13 +1,13 @@
-;; Test that we get a parser error when we have a debug assign record that does
-;; not use an inline DIExpression for its address expression.
+;; Test that we get a parser error when we have a debug record with an
+;; incorrect number of arguments.
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
; ModuleID = '<stdin>'
source_filename = "<stdin>"
define dso_local i32 @f(i32 %a) !dbg !7 {
entry:
-; CHECK: <stdin>:[[@LINE+1]]:63: error: expected valid inline DIExpression here
- #dbg_assign(i32 %a, !12, !DIExpression(), !15, ptr undef, !20, !14)
+; CHECK: <stdin>:[[@LINE+1]]:46: error: expected '!' here
+ #dbg_value(i32 %a, !12, !DIExpression(), i32 0)
ret i32 %a, !dbg !18
}
@@ -34,4 +34,3 @@ entry:
!16 = !DILocation(line: 3, column: 20, scope: !7)
!17 = !DILocation(line: 3, column: 25, scope: !7)
!18 = !DILocation(line: 3, column: 30, scope: !7)
-!20 = !DIExpression()
>From 5702fea17e487ca97073a7eb0f2e157026ffa412 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Mon, 4 Mar 2024 17:00:33 +0000
Subject: [PATCH 10/10] clang-format
---
.../include/llvm/IR/DebugProgramInstruction.h | 4 ++--
llvm/lib/AsmParser/LLParser.cpp | 24 +++++++++----------
llvm/lib/IR/DebugProgramInstruction.cpp | 11 +++++----
llvm/lib/IR/Verifier.cpp | 2 +-
4 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index 4253f549b5697b..a8faf415a3ea87 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -227,6 +227,7 @@ class DPLabel : public DbgRecord {
/// "createUnresolvedDPLabel", which clearly expresses that it is for parsing
/// only.
DPLabel(MDNode *Label, MDNode *DL);
+
public:
DPLabel(DILabel *Label, DebugLoc DL);
@@ -313,8 +314,7 @@ class DPValue : public DbgRecord, protected DebugValueUser {
/// necessary fields are empty or unused fields are not empty, i.e. if the
/// #dbg_assign fields are used for a non-dbg-assign type.
static DPValue *createUnresolvedDPValue(LocationType Type, Metadata *Val,
- MDNode *Variable,
- MDNode *Expression,
+ MDNode *Variable, MDNode *Expression,
MDNode *AssignID, Metadata *Address,
MDNode *AddressExpression,
MDNode *DI);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 02c32cff3c53a7..6079232cd76bf8 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6422,9 +6422,7 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// Parse the instructions and debug values in this block until we get a
// terminator.
Instruction *Inst;
- auto DeleteDbgRecord = [](DbgRecord *DR) {
- DR->deleteRecord();
- };
+ auto DeleteDbgRecord = [](DbgRecord *DR) { DR->deleteRecord(); };
using DbgRecordPtr = std::unique_ptr<DbgRecord, decltype(DeleteDbgRecord)>;
SmallVector<DbgRecordPtr> TrailingDbgRecord;
do {
@@ -6514,10 +6512,10 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
if (Lex.getKind() != lltok::DbgRecordType)
return error(DPVLoc, "expected debug record type here");
RecordKind RecordType = StringSwitch<RecordKind>(Lex.getStrVal())
- .Case("declare", RecordKind::ValueKind)
- .Case("value", RecordKind::ValueKind)
- .Case("assign", RecordKind::ValueKind)
- .Case("label", RecordKind::LabelKind);
+ .Case("declare", RecordKind::ValueKind)
+ .Case("value", RecordKind::ValueKind)
+ .Case("assign", RecordKind::ValueKind)
+ .Case("label", RecordKind::LabelKind);
// Parsing labels is trivial; parse here and early exit, otherwise go into the
// full DPValue processing stage.
@@ -6540,9 +6538,9 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
}
LocType ValueType = StringSwitch<LocType>(Lex.getStrVal())
- .Case("declare", LocType::Declare)
- .Case("value", LocType::Value)
- .Case("assign", LocType::Assign);
+ .Case("declare", LocType::Declare)
+ .Case("value", LocType::Value)
+ .Case("assign", LocType::Assign);
Lex.Lex();
if (parseToken(lltok::lparen, "Expected '(' here"))
@@ -6600,9 +6598,9 @@ bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) {
if (parseToken(lltok::rparen, "Expected ')' here"))
return true;
- DR = DPValue::createUnresolvedDPValue(
- ValueType, ValLocMD, Variable, Expression, AssignID,
- AddressLocation, AddressExpression, DebugLoc);
+ DR = DPValue::createUnresolvedDPValue(ValueType, ValLocMD, Variable,
+ Expression, AssignID, AddressLocation,
+ AddressExpression, DebugLoc);
return false;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index dbeaa674106098..5ff1e8c19db68b 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -138,11 +138,11 @@ DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
llvm_unreachable("unsupported DbgRecord kind");
}
-
DPLabel::DPLabel(MDNode *Label, MDNode *DL)
: DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {
assert(Label && "Unexpected nullptr");
- assert((isa<DILabel>(Label) || Label->isTemporary()) && "Label type must be or resolve to a DILabel");
+ assert((isa<DILabel>(Label) || Label->isTemporary()) &&
+ "Label type must be or resolve to a DILabel");
}
DPLabel::DPLabel(DILabel *Label, DebugLoc DL)
: DbgRecord(LabelKind, DL), Label(Label) {
@@ -156,13 +156,14 @@ DPLabel *DPLabel::createUnresolvedDPLabel(MDNode *Label, MDNode *DL) {
DPValue::DPValue(DPValue::LocationType Type, Metadata *Val, MDNode *Variable,
MDNode *Expression, MDNode *AssignID, Metadata *Address,
MDNode *AddressExpression, MDNode *DI)
- : DbgRecord(ValueKind, DebugLoc(DI)), DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),
+ : DbgRecord(ValueKind, DebugLoc(DI)),
+ DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),
Expression(Expression), AddressExpression(AddressExpression) {}
DPValue *DPValue::createUnresolvedDPValue(DPValue::LocationType Type,
Metadata *Val, MDNode *Variable,
- MDNode *Expression,
- MDNode *AssignID, Metadata *Address,
+ MDNode *Expression, MDNode *AssignID,
+ Metadata *Address,
MDNode *AddressExpression,
MDNode *DI) {
return new DPValue(Type, Val, Variable, Expression, AssignID, Address,
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index eea98946d6feb4..220d028ddc4d60 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -684,7 +684,7 @@ void Verifier::visitDbgRecords(Instruction &I) {
&I);
CheckDI(!isa<PHINode>(&I) || !I.hasDbgValues(),
"PHI Node must not have any attached DbgRecords", &I);
- //for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
+ // for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
for (DbgRecord &DR : I.getDbgValueRange()) {
CheckDI(DR.getMarker() == I.DbgMarker, "DbgRecord had invalid DbgMarker",
&I, &DR);
More information about the llvm-commits
mailing list