forked from OSchip/llvm-project
IRMover: Account for matching types present across modules
Summary: 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. Reviewers: pcc, tejohnson Reviewed By: pcc, tejohnson Subscribers: tobiasvk, mehdi_amini, steven_wu, llvm-commits, kcc Differential Revision: https://reviews.llvm.org/D47898 llvm-svn: 335145
This commit is contained in:
parent
6fa24b0b7f
commit
34b9112216
|
@ -241,18 +241,27 @@ Type *TypeMapTy::get(Type *Ty, SmallPtrSet<StructType *, 8> &Visited) {
|
||||||
// These are types that LLVM itself will unique.
|
// These are types that LLVM itself will unique.
|
||||||
bool IsUniqued = !isa<StructType>(Ty) || cast<StructType>(Ty)->isLiteral();
|
bool IsUniqued = !isa<StructType>(Ty) || cast<StructType>(Ty)->isLiteral();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (!IsUniqued) {
|
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->getContext().isODRUniquingDebugTypes() && !STy->isOpaque() &&
|
||||||
|
DstStructTypesSet.hasType(STy))
|
||||||
|
return *Entry = STy;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
for (auto &Pair : MappedTypes) {
|
for (auto &Pair : MappedTypes) {
|
||||||
assert(!(Pair.first != Ty && Pair.second == Ty) &&
|
assert(!(Pair.first != Ty && Pair.second == Ty) &&
|
||||||
"mapping to a source type");
|
"mapping to a source type");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!IsUniqued && !Visited.insert(cast<StructType>(Ty)).second) {
|
if (!Visited.insert(STy).second) {
|
||||||
StructType *DTy = StructType::create(Ty->getContext());
|
StructType *DTy = StructType::create(Ty->getContext());
|
||||||
return *Entry = DTy;
|
return *Entry = DTy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is not a recursive type, then just map all of the elements and
|
// If this is not a recursive type, then just map all of the elements and
|
||||||
|
|
|
@ -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)
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue