[PATCH] D47898: IRMover: Account for matching types present across modules

Vlad Tsyrklevich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 7 11:46:36 PDT 2018


vlad.tsyrklevich created this revision.
vlad.tsyrklevich added reviewers: pcc, tejohnson.
Herald added subscribers: llvm-commits, steven_wu, mehdi_amini.

Due to uniqueing of DICompositeTypes, it's possible for a type from one
module to be loaded into another earlier module without being renamed.
Then when the defining module is being IRMoved, the type can be used as
a Mapping destination before being loaded, such that when it's requested
using TypeMapTy::get() it will fail with an assertion that the type is a
source type when it's actually a type in both the source and
destination modules. Correctly handle that case by allowing a non-opaque
non-literal struct type be present in both modules.

Fix for PR37684.


Repository:
  rL LLVM

https://reviews.llvm.org/D47898

Files:
  lib/Linker/IRMover.cpp
  test/LTO/X86/Inputs/type-mapping-bug2.ll
  test/LTO/X86/type-mapping-bug2.ll


Index: test/LTO/X86/type-mapping-bug2.ll
===================================================================
--- /dev/null
+++ test/LTO/X86/type-mapping-bug2.ll
@@ -0,0 +1,42 @@
+; RUN: opt -module-summary -o %t0.o %S/Inputs/type-mapping-bug2.ll
+; RUN: opt -module-summary -o %t1.o %s
+; RUN: llvm-lto2 run -o %t2 %t0.o %t1.o -r %t0.o,c,px -r %t1.o,a,px -r %t1.o,b,px
+;
+; Test for the issue described in https://bugs.llvm.org/show_bug.cgi?id=37684
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; T1 will be linked against T2 because T2 was already loaded in %t0.o due to
+; the declaration for @b being imported due to !13
+%"T1" = type {}
+%"T2" = type {}
+
+define %"T1" @a() {
+  unreachable
+}
+
+define i1 @b(%"T2"*) {
+  unreachable
+}
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{i32 1, !"ThinLTO", i32 0}
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4)
+!3 = !DIFile(filename: "f1", directory: "")
+!4 = !{!5, !9}
+!5 = !DICompositeType(tag: DW_TAG_class_type, file: !3, templateParams: !6, scope: !8)
+!6 = !{!7}
+
+; The reference to @b and T2 that will be loaded in %t0.o
+
+!7 = !DITemplateValueParameter(value: i1 (%"T2"*)* @b)
+!8 = distinct !DISubprogram(unit: !2)
+
+; This DICompositeType is uniqued against !5 in Inputs/type-mapping-bug2.ll,
+; causing !7 and hence %T2 to be loaded into it's module
+
+!9 = !DICompositeType(tag: DW_TAG_array_type, identifier: "SHARED", scope: !8)
+
Index: test/LTO/X86/Inputs/type-mapping-bug2.ll
===================================================================
--- /dev/null
+++ test/LTO/X86/Inputs/type-mapping-bug2.ll
@@ -0,0 +1,16 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @c() !dbg !6 {
+  unreachable
+}
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{i32 1, !"ThinLTO", i32 0}
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4)
+!3 = !DIFile(filename: "f2", directory: "")
+!4 = !{!5}
+!5 = !DICompositeType(tag: DW_TAG_class_type, file: !3, flags: DIFlagFwdDecl, identifier: "SHARED")
+!6 = distinct !DISubprogram(unit: !2)
Index: lib/Linker/IRMover.cpp
===================================================================
--- lib/Linker/IRMover.cpp
+++ lib/Linker/IRMover.cpp
@@ -241,14 +241,22 @@
   // These are types that LLVM itself will unique.
   bool IsUniqued = !isa<StructType>(Ty) || cast<StructType>(Ty)->isLiteral();
 
-#ifndef NDEBUG
   if (!IsUniqued) {
+    StructType *STy = cast<StructType>(Ty);
+    // This is actually a type from the destination module, this can be reached
+    // when this type is loaded in another module, added to DstStructTypesSet,
+    // and then we reach the same type in another module where it has not been
+    // added to MappedTypes. (PR37684)
+    if (!STy->isOpaque() && DstStructTypesSet.hasType(STy))
+      return *Entry = STy;
+
+#ifndef NDEBUG
     for (auto &Pair : MappedTypes) {
       assert(!(Pair.first != Ty && Pair.second == Ty) &&
              "mapping to a source type");
     }
-  }
 #endif
+  }
 
   if (!IsUniqued && !Visited.insert(cast<StructType>(Ty)).second) {
     StructType *DTy = StructType::create(Ty->getContext());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47898.150375.patch
Type: text/x-patch
Size: 3414 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180607/ae0441d6/attachment.bin>


More information about the llvm-commits mailing list