[llvm] [DebugInfo] Add Verifier check for duplicate arg indices in SP's retainedNodes list (PR #186225)

via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 12 12:55:17 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-debuginfo

Author: Vladislav Dzhidzhoev (dzhidzhoev)

<details>
<summary>Changes</summary>

DwarfFile asserts if two arguments of the same subprogram with the same index are present in a DISubprogram scope (https://github.com/llvm/llvm-project/blob/5d7a502a9d923784abe4382ec479ee1c0667d743/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp#L110). This patch adds a check to the Verifier to detect such invalid IR earlier. It can be helpful for finding reproducers for bugs like https://issues.chromium.org/issues/40288032.

The incorrect args field of DILocalVariable in llvm/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir is fixed.

---
Full diff: https://github.com/llvm/llvm-project/pull/186225.diff


2 Files Affected:

- (modified) llvm/lib/IR/Verifier.cpp (+11) 
- (modified) llvm/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir (+1-1) 


``````````diff
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 3784ee00811f8..f794fa29cbf4c 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1627,6 +1627,8 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
   if (auto *RawNode = N.getRawRetainedNodes()) {
     auto *Node = dyn_cast<MDTuple>(RawNode);
     CheckDI(Node, "invalid retained nodes list", &N, RawNode);
+
+    MapVector<unsigned, DILocalVariable *> Args;
     for (Metadata *Op : Node->operands()) {
       CheckDI(Op, "nullptr in retained nodes", &N, Node);
 
@@ -1654,6 +1656,15 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
           "invalid retained nodes, retained node does not belong to subprogram",
           &N, Node, RetainedNode, RetainedNodeScope, RetainedNodeSP,
           RetainedNodeUnit);
+
+      auto *DV = dyn_cast<DILocalVariable>(RetainedNode);
+      if (!DV)
+        continue;
+      if (unsigned ArgNum = DV->getArg()) {
+        auto [ArgI, Inserted] = Args.insert({ArgNum, DV});
+        CheckDI(Inserted || DV == ArgI->second, "invalid retained nodes, more than one local variable with the same argument index",
+            &N, N.getUnit(), Node, RetainedNode, Args[ArgNum]);
+      }
     }
   }
   CheckDI(!hasConflictingReferenceFlags(N.getFlags()),
diff --git a/llvm/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir b/llvm/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
index 1f9cc7542fd96..abd50477f3d08 100644
--- a/llvm/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
+++ b/llvm/test/DebugInfo/MIR/X86/live-debug-values-reg-copy.mir
@@ -95,7 +95,7 @@
   !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
   !11 = !{!12, !13}
   !12 = !DILocalVariable(name: "arg1", arg: 1, scope: !7, file: !1, line: 6, type: !10)
-  !13 = !DILocalVariable(name: "var1", arg: 1, scope: !7, file: !1, line: 6, type: !10)
+  !13 = !DILocalVariable(name: "var1", scope: !7, file: !1, line: 6, type: !10)
   !15 = !DILocation(line: 6, column: 13, scope: !7)
   !20 = !{!21, !21, i64 0}
   !21 = !{!"int", !22, i64 0}

``````````

</details>


https://github.com/llvm/llvm-project/pull/186225


More information about the llvm-commits mailing list