This is an archive of the discontinued LLVM Phabricator instance.

[IRMover] Don't materialise values from different source module
Needs ReviewPublic

Authored by evgeny777 on Jul 31 2018, 7:27 AM.

Details

Summary

This fixes PR38372

Diff Detail

Event Timeline

evgeny777 created this revision.Jul 31 2018, 7:27 AM

Can you add a bit more explanation other than just saying fixing PR38372?

test/ThinLTO/X86/fwd-decl.ll
23

I don't think debug info are relevant for the test case. You can remove them from both module.

evgeny777 added inline comments.Jul 31 2018, 10:02 AM
test/ThinLTO/X86/fwd-decl.ll
23

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.

steven_wu added inline comments.Jul 31 2018, 11:48 AM
test/ThinLTO/X86/fwd-decl.ll
23

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.

Any comments? Teresa?

tejohnson accepted this revision.Aug 10 2018, 8:06 AM

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.

This revision is now accepted and ready to land.Aug 10 2018, 8:06 AM

Hi @evgeny777 @tejohnson

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)

tejohnson requested changes to this revision.Aug 13 2018, 6:37 AM

That new DITemplateValueParameter type doesn't look correct to me.

This revision now requires changes to proceed.Aug 13 2018, 6:37 AM
evgeny777 updated this revision to Diff 160539.EditedAug 14 2018, 2:33 AM

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?

evgeny777 added a comment.EditedAug 14 2018, 2:46 AM

That new DITemplateValueParameter type doesn't look correct to me.

I'm getting !DITemplateValueParameter(value: null) when module is passed to optimizer. This isn't correct either, but module is no longer broken.

That new DITemplateValueParameter type doesn't look correct to me.

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 Do you mind I give this bug a try ? Thanks.

@trentxintong Sure, please go on. I'm on vacation till Sep, 12

@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 ?