This fixes PR38372
Diff Detail
Event Timeline
Can you add a bit more explanation other than just saying fixing PR38372?
test/ThinLTO/X86/fwd-decl.ll | ||
---|---|---|
24 | I don't think debug info are relevant for the test case. You can remove them from both module. |
test/ThinLTO/X86/fwd-decl.ll | ||
---|---|---|
24 | No, I can't The DIFlagFwdDecl forces IRMover to look for definition in a different module, which has also been loaded by LTO. This causes IRMover to see both %struct.TA = type {} and %struct.TA = type opaque during a single move operation and make a mixture of types in a destination module. Removal of debug info also eliminates the error. |
test/ThinLTO/X86/fwd-decl.ll | ||
---|---|---|
24 | Will be good if you put the information into the commit message. That makes sense now. Thanks for explanation. LGTM. But I will wait for Teresa to take a look. Thanks for fixing this. |
Sorry for the late reply - I am just today back from vacation and catching up. This LGTM, but as Steven noted, please add a description to the commit message.
I dumped the Composite right after the 2nd file is merged. Things look good except the DITemplateValueParameter debuginfo looks a bit odd. Does this look correct to you ?
(gdb) p Composite.dump()
; ModuleID = 'ld-temp.o'
source_filename = "ld-temp.o"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%struct.TA = type {}
@gv = external dso_local global %struct.TA*
define i32 @c() !dbg !13 {
%1 = bitcast %struct.TA** @gv to i8* unreachable
}
define i1 @b(%struct.TA*) {
unreachable
}
define i1 @a(%struct.TA*) {
%2 = call i1 @b(%struct.TA* %0) unreachable
}
!llvm.dbg.cu = !{!0, !6}
!llvm.module.flags = !{!11, !12}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, retainedTypes: !2)
!1 = !DIFile(filename: "f2", directory: "")
!2 = !{!3}
!3 = distinct !DICompositeType(tag: DW_TAG_class_type, scope: !5, file: !4, identifier: "SHARED")
!4 = !DIFile(filename: "f1", directory: "")
!5 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !6)
!6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, retainedTypes: !7)
!7 = !{!8, !3}
!8 = !DICompositeType(tag: DW_TAG_class_type, scope: !5, file: !4, templateParams: !9)
!9 = !{!10}
!10 = !DITemplateValueParameter(value: i1 (%"type 0x4439360"*)* @b)
!11 = !{i32 2, !"Debug Info Version", i32 3}
!12 = !{i32 1, !"ThinLTO", i32 0}
!13 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !0)
It turned out that the problem is more complex than it seemed initially, because this forward declaration causes metadata loader to do really horrible things. Here is how metadata of test/ThinLTO/X86/fwd-decl.ll looks after both modules are loaded by addRegularLTO:
!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, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, retainedTypes: !4) !3 = !DIFile(filename: "f2", directory: "") !4 = !{!5} !5 = distinct !DICompositeType(tag: DW_TAG_array_type, scope: !6, identifier: "SHARED") !6 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !7) !7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !8, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, retainedTypes: !9) !8 = !DIFile(filename: "f1", directory: "") !9 = !{!10, !5} !10 = !DICompositeType(tag: DW_TAG_class_type, scope: !6, file: !8, templateParams: !11) !11 = !{!12} !12 = !DITemplateValueParameter(value: i1 (%struct.TA.0*)* @b)
Note that module metadata now contains both compile units. The module itself is broken because %struct.TA.0 is not defined (it is defined in Inputs/fwd-decl.ll after renaming)
This combined with metadata caching in IRMover causes bug found by @trentxintong.
One possible way to fix it is to disable metadata caching for specific module when metadata import causes materialising of GV from a different source module (see updated patch).
Just curious: how such debugging info was produced? Is it synthetic example or is it derived from real compiler output?
I'm getting !DITemplateValueParameter(value: null) when module is passed to optimizer. This isn't correct either, but module is no longer broken.
I've added @dblaikie to the review to comment on what the debug metadata should look like in this case.
[...]
Note that module metadata now contains both compile units. The module itself is broken because %struct.TA.0 is not defined (it is defined in Inputs/fwd-decl.ll after renaming)
This combined with metadata caching in IRMover causes bug found by @trentxintong.
One possible way to fix it is to disable metadata caching for specific module when metadata import causes materialising of GV from a different source module (see updated patch).Just curious: how such debugging info was produced? Is it synthetic example or is it derived from real compiler output?
I think @trentxintong mentioned this was reduced from an application. Out of curiosity, what makes it look like it might be synthetic?
Out of curiosity, what makes it look like it might be synthetic?
I'm not a debug info expert, but this looks unusual:
!8 = distinct !DISubprogram(unit: !2) !9 = !DICompositeType(tag: DW_TAG_array_type, identifier: "SHARED", scope: !8)
With no code in Inputs/fwd-decl.ll actually referencing !8 or !9
@evgeny777
Thanks!. The approach I am considering is to bring in something, like a stub (e.g. the declaration completely unmapped, we cant map it fully anyways) and eventually using it as a handle to RAUW when we have properly mapped in the SGV. Do you think this would work ?
I don't think debug info are relevant for the test case. You can remove them from both module.