[llvm] b575405 - Verifier: accept enums as scopes

Yuanfang Chen via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 10 12:20:49 PST 2021


Author: Augie Fackler
Date: 2021-12-10T12:19:56-08:00
New Revision: b575405cc3a53112c487fd2dab2d3ed75c3944ab

URL: https://github.com/llvm/llvm-project/commit/b575405cc3a53112c487fd2dab2d3ed75c3944ab
DIFF: https://github.com/llvm/llvm-project/commit/b575405cc3a53112c487fd2dab2d3ed75c3944ab.diff

LOG: Verifier: accept enums as scopes

Rust allows enums to be scopes, as shown by the previous change. Sadly,
D111770 disallowed enums-as-scopes in the LLVM Verifier, which means
that LLVM HEAD stopped working for Rust compiles.  As a result, we back
out the verifier part of D111770 with a modification to the testcase so
we don't break this in the future.

The testcase is now actual IR from rustc at commit 8f8092cc3, which is
the nightly as of 2021-09-28. I would expect rustc 1.57 to produce
similar or identical IR if someone wants to reproduce this IR in the
future with minimal changes. A recipe for reproducing the IR using rustc
is included in the test file.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D115353

Added: 
    llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll

Modified: 
    llvm/lib/IR/Verifier.cpp

Removed: 
    llvm/test/Verifier/dbg-invalid-enum-as-scope.ll


################################################################################
diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 42158ef681e53..4cb18fc3ed946 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -553,8 +553,6 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
   void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
                            const Value *V, bool IsIntrinsic);
   void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
-  template <typename T>
-  void verifyODRTypeAsScopeOperand(const MDNode &MD, T * = nullptr);
 
   void visitConstantExprsRecursively(const Constant *EntryC);
   void visitConstantExpr(const ConstantExpr *CE);
@@ -864,19 +862,6 @@ void Verifier::visitNamedMDNode(const NamedMDNode &NMD) {
   }
 }
 
-template <typename T>
-void Verifier::verifyODRTypeAsScopeOperand(const MDNode &MD, T *) {
-  if (isa<T>(MD)) {
-    if (auto *N = dyn_cast_or_null<DICompositeType>(cast<T>(MD).getScope()))
-      // Of all the supported tags for DICompositeType(see visitDICompositeType)
-      // we know that enum type cannot be a scope.
-      AssertDI(N->getTag() != dwarf::DW_TAG_enumeration_type,
-               "enum type is not a scope; check enum type ODR "
-               "violation",
-               N, &MD);
-  }
-}
-
 void Verifier::visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs) {
   // Only visit each node once.  Metadata can be mutually recursive, so this
   // avoids infinite recursion here, as well as being an optimization.
@@ -886,12 +871,6 @@ void Verifier::visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs) {
   Assert(&MD.getContext() == &Context,
          "MDNode context does not match Module context!", &MD);
 
-  // Makes sure when a scope operand is a ODR type, the ODR type uniquing does
-  // not create invalid debug metadata.
-  // TODO: check that the non-ODR-type scope operand is valid.
-  verifyODRTypeAsScopeOperand<DIType>(MD);
-  verifyODRTypeAsScopeOperand<DILocalScope>(MD);
-
   switch (MD.getMetadataID()) {
   default:
     llvm_unreachable("Invalid MDNode subclass");

diff  --git a/llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll b/llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll
new file mode 100644
index 0000000000000..b6a53bd4c4597
--- /dev/null
+++ b/llvm/test/DebugInfo/dbg-rust-valid-enum-as-scope.ll
@@ -0,0 +1,74 @@
+; RUN: %llc_dwarf -filetype=obj -o - %s | llvm-dwarfdump -| FileCheck --implicit-check-not=DW_TAG --implicit-check-not=NULL %s
+; CHECK: DW_TAG_compile_unit
+; CHECK:   DW_AT_language	(DW_LANG_Rust)
+; CHECK:   DW_TAG_namespace
+; CHECK:     DW_TAG_enumeration_type
+; CHECK:     DW_AT_name	("E")
+; CHECK:       DW_TAG_enumerator
+; CHECK:       DW_TAG_enumerator
+; CHECK:       DW_TAG_subprogram
+; CHECK:         DW_AT_name	("f")
+; CHECK:         DW_TAG_formal_parameter
+; CHECK:         NULL
+; CHECK:       NULL
+; CHECK:     NULL
+; CHECK:   DW_TAG_pointer_type
+; CHECK:   NULL
+
+; This file comes from rustc output, with the input program
+;         pub enum E { A, B }
+;         impl E {
+;             pub fn f(&self) {}
+;         }
+; compiled with `rustc --crate-type=lib a.rs --emit llvm-ir -g` and
+; copying the resulting `a.ll` file to here. This was done with rustc
+; at nightly from 2021-09-28 (git 8f8092cc3), but rustc 1.57 should
+; produce similar or identical output.
+
+; ModuleID = 'a.a146b597-cgu.0'
+source_filename = "a.a146b597-cgu.0"
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.0"
+
+; a::E::f
+; Function Attrs: uwtable
+define void @_ZN1a1E1f17h4fcb50ce732fb2a7E(i8* align 1 dereferenceable(1) %self) unnamed_addr #0 !dbg !13 {
+start:
+  %self.dbg.spill = alloca i8*, align 8
+  store i8* %self, i8** %self.dbg.spill, align 8
+  call void @llvm.dbg.declare(metadata i8** %self.dbg.spill, metadata !19, metadata !DIExpression()), !dbg !21
+  ret void, !dbg !22
+}
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+attributes #0 = { uwtable "frame-pointer"="all" "probe-stack"="__rust_probestack" "target-cpu"="core2" }
+attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.dbg.cu = !{!3}
+
+!0 = !{i32 7, !"PIC Level", i32 2}
+!1 = !{i32 2, !"Dwarf Version", i32 2}
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !4, producer: "clang LLVM (rustc version 1.57.0-nightly (8f8092cc3 2021-09-28))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !5)
+!4 = !DIFile(filename: "a.rs/@/a.a146b597-cgu.0", directory: "/Users/augie")
+!5 = !{!6}
+!6 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E", scope: !8, file: !7, baseType: !9, size: 8, align: 8, flags: DIFlagEnumClass, elements: !10)
+!7 = !DIFile(filename: "<unknown>", directory: "")
+!8 = !DINamespace(name: "a", scope: null)
+!9 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
+!10 = !{!11, !12}
+!11 = !DIEnumerator(name: "A", value: 0)
+!12 = !DIEnumerator(name: "B", value: 1)
+!13 = distinct !DISubprogram(name: "f", linkageName: "_ZN1a1E1f17h4fcb50ce732fb2a7E", scope: !6, file: !14, line: 3, type: !15, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !3, templateParams: !20, retainedNodes: !18)
+!14 = !DIFile(filename: "a.rs", directory: "/Users/augie", checksumkind: CSK_MD5, checksum: "ab4ce84c27ef6fd0be1ef78e8131faa8")
+!15 = !DISubroutineType(types: !16)
+!16 = !{null, !17}
+!17 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&E", baseType: !6, size: 64, align: 64, dwarfAddressSpace: 0)
+!18 = !{!19}
+!19 = !DILocalVariable(name: "self", arg: 1, scope: !13, file: !14, line: 3, type: !17)
+!20 = !{}
+!21 = !DILocation(line: 3, column: 14, scope: !13)
+!22 = !DILocation(line: 3, column: 23, scope: !13)

diff  --git a/llvm/test/Verifier/dbg-invalid-enum-as-scope.ll b/llvm/test/Verifier/dbg-invalid-enum-as-scope.ll
deleted file mode 100644
index 4053d4aede2e2..0000000000000
--- a/llvm/test/Verifier/dbg-invalid-enum-as-scope.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: llvm-as -disable-output <%s 2>&1 | FileCheck %s
-; CHECK: enum type is not a scope; check enum type ODR violation
-; CHECK: warning: ignoring invalid debug info
-
-!llvm.module.flags = !{!0}
-!0 = !{i32 2, !"Debug Info Version", i32 3}
-!llvm.dbg.cu = !{!1}
-!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !13, enums: !3)
-!2 = !DIFile(filename: "file.c", directory: "dir")
-!3 = !{!4}
-!4 = distinct !DICompositeType(tag: DW_TAG_enumeration_type, name: "Stage", file: !2, line: 3, baseType: !10, size: 32, elements: !11, identifier: "_ZTS5Stage")
-!6 = !DIDerivedType(tag: DW_TAG_member, name: "Var", scope: !4, file: !2, line: 5, baseType: !10)
-!10 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
-!11 = !{!12}
-!12 = !DIEnumerator(name: "A1", value: 0, isUnsigned: true)
-!13 = !{!6}


        


More information about the llvm-commits mailing list