| commit 8b46544641ef49e20621a3ac8e14fd4c95338522 |
| Author: Pirama Arumuga Nainar <pirama@google.com> |
| Date: Wed Sep 11 18:35:49 2019 +0000 |
| |
| [IRMover] Don't map globals if their types are the same |
| |
| Summary: |
| During IR Linking, if the types of two globals in destination and source |
| modules are the same, it can only be because the global in the |
| destination module is originally from the source module and got added to |
| the destination module from a shared metadata. |
| |
| We shouldn't map this type to itself in case the type's components get |
| remapped to a new type from the destination (for instance, during the |
| loop over SrcM->getIdentifiedStructTypes() further below in |
| IRLinker::computeTypeMapping()). |
| |
| Fixes PR40312. |
| |
| Reviewers: tejohnson, pcc, srhines |
| |
| Subscribers: mehdi_amini, hiraditya, steven_wu, dexonsmith, llvm-commits |
| |
| Tags: #llvm |
| |
| Differential Revision: https://reviews.llvm.org/D66814 |
| |
| llvm-svn: 371643 |
| |
| diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp |
| index 8e89724d443..aee89af88a6 100644 |
| --- a/llvm/lib/Linker/IRMover.cpp |
| +++ b/llvm/lib/Linker/IRMover.cpp |
| @@ -758,8 +758,18 @@ void IRLinker::computeTypeMapping() { |
| } |
| |
| for (GlobalValue &SGV : *SrcM) |
| - if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) |
| + if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) { |
| + if (DGV->getType() == SGV.getType()) { |
| + // If the types of DGV and SGV are the same, it means that DGV is from |
| + // the source module and got added to DstM from a shared metadata. We |
| + // shouldn't map this type to itself in case the type's components get |
| + // remapped to a new type from DstM (for instance, during the loop over |
| + // SrcM->getIdentifiedStructTypes() below). |
| + continue; |
| + } |
| + |
| TypeMap.addTypeMapping(DGV->getType(), SGV.getType()); |
| + } |
| |
| for (GlobalValue &SGV : SrcM->aliases()) |
| if (GlobalValue *DGV = getLinkedToGlobal(&SGV)) |
| diff --git a/llvm/test/LTO/X86/Inputs/type-mapping-bug3.ll b/llvm/test/LTO/X86/Inputs/type-mapping-bug3.ll |
| new file mode 100644 |
| index 00000000000..d6fe8e83a78 |
| --- /dev/null |
| +++ b/llvm/test/LTO/X86/Inputs/type-mapping-bug3.ll |
| @@ -0,0 +1,26 @@ |
| +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| +target triple = "x86_64-unknown-linux-gnu" |
| + |
| +; T2 is the non-opaque struct required to trigger the uniqued T2.0 and T3.0 to |
| +; respectively T2 and T3 in the destination module. |
| +%"T2" = type { %"T3"* } |
| +%"T3" = type opaque |
| + |
| +; Use/refer to T2 so it gets added as an IdentifiedStructType. The debug |
| +; reference to !6 is required to transitively load the metadata !5. |
| +define void @a(%"T2") !dbg !6 { |
| + ret void |
| +} |
| + |
| +!llvm.module.flags = !{!0, !1} |
| +!llvm.dbg.cu = !{!2} |
| +!0 = !{i32 1, !"ThinLTO", i32 0} |
| +!1 = !{i32 2, !"Debug Info Version", i32 3} |
| +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4) |
| +!3 = !DIFile(filename: "f2", directory: "") |
| +!4 = !{!5} |
| + |
| +; This DICompositeType refers to !5 in type-mapping-bug3.ll |
| +!5 = !DICompositeType(tag: DW_TAG_structure_type, flags: DIFlagFwdDecl, identifier: "SHARED") |
| + |
| +!6 = distinct !DISubprogram(unit: !2) |
| diff --git a/llvm/test/LTO/X86/type-mapping-bug3.ll b/llvm/test/LTO/X86/type-mapping-bug3.ll |
| new file mode 100644 |
| index 00000000000..2f845a56a92 |
| --- /dev/null |
| +++ b/llvm/test/LTO/X86/type-mapping-bug3.ll |
| @@ -0,0 +1,47 @@ |
| +; RUN: opt -module-summary -o %t0.o %S/Inputs/type-mapping-bug3.ll |
| +; RUN: opt -module-summary -o %t1.o %s |
| +; RUN: llvm-lto2 run -o %t2 %t0.o %t1.o -r %t0.o,a,px -r %t1.o,b,px -r %t1.o,c,px -r %t1.o,d, |
| +; |
| +; Test for the issue described in https://bugs.llvm.org/show_bug.cgi?id=40312 |
| + |
| +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| +target triple = "x86_64-unknown-linux-gnu" |
| + |
| +; T2 is the non-opaque struct required to trigger the uniqued T2.0 and T3.0 to |
| +; respectively T2 and T3 in the destination module. |
| +%"T2" = type { %"T3"* } |
| +%"T3" = type opaque |
| + |
| +; Use/refer to T2 so it gets added as an IdentifiedStructType. |
| +define void @c(%"T2") { |
| + unreachable |
| +} |
| + |
| +; The global declaration that causes the assertion when its type is mapped to |
| +; itself incorrectly. |
| +declare void @d(%"T3"*) |
| + |
| +define void @b() { |
| +entry: |
| + %f.addr = alloca %"T3"*load %"T3"*, %"T3"** %f.addr |
| + |
| + ; The call with the getCalledValue() vs getCalledFunction() mismatch. |
| + call void @d(%"T3"* %0) |
| + unreachable |
| +} |
| + |
| +!llvm.dbg.cu = !{!2} |
| +!llvm.module.flags = !{!0, !1} |
| +!0 = !{i32 1, !"ThinLTO", i32 0} |
| +!1 = !{i32 2, !"Debug Info Version", i32 3} |
| +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, retainedTypes: !4) |
| +!3 = !DIFile(filename: "f1", directory: "") |
| +!4 = !{!5} |
| + |
| +; This DICompositeType is referenced by !5 in Inputs/type-mapping-bug3.ll |
| +; causing the function type in !7 to be added to its module. |
| +!5 = !DICompositeType(tag: DW_TAG_structure_type, templateParams: !6, identifier: "SHARED") |
| +!6 = !{!7} |
| + |
| +; The reference to d and T3 that gets loaded into %t0.o |
| +!7 = !DITemplateValueParameter(value: void (%"T3"*)* @d) |