Open dschuff opened 9 years ago
Ah, that does sound like it could be an LTO bug:
Build one object (bitcode) file without debug info Build one object (bitcode) file with debug info.
Have the same comdat function in both.
Choose the non-debug-having implementation of the function, while keeping the subprogram debug info from the debug-having implementation.
Duncan, does that sound like a thing that can/would happen?
Yes, that sounds possible.
Once we put subprogram debug info as a function metadata attachment, would that fix this bug?
Yes, I think so. That's tracked by bug 23367, which I'm hoping to get back to soon (along with a bunch of follow-ups).
Ah, that does sound like it could be an LTO bug:
Build one object (bitcode) file without debug info Build one object (bitcode) file with debug info.
Have the same comdat function in both.
Choose the non-debug-having implementation of the function, while keeping the subprogram debug info from the debug-having implementation.
Duncan, does that sound like a thing that can/would happen?
Once we put subprogram debug info as a function metadata attachment, would that fix this bug?
In my linked bitcode file, there are some calls to middle which have dbg attachments (in this case from libgtest, which is built with debug info), and some calls which do not (other user files built without debug info). Middle is a comdat function, and the one included in the link output has no dbg attachments (presumably the copies from those files that were built with debug info had the attachments). There is also a DISubprogram for middle. I guess if the callee (middle) has no dbg attachements it should not have a DISubprogram? I guess I should look at the behavior of the linker in that case?
This file is the result of a bitcode link of some files which have debug info (libc++) and some which do not (all the user files).
I'll try to see if the invariant you mentioned is getting violated in that process. It's also possible that one of the passes we run is dropping something it shouldn't.
Hm, interesting. in my repro there is a DISubprogram for the middle function, but the function itself has no dbg attachments. Maybe that is the underlying unexpected thing?
Yes, that's likely to be a bad thing. The current requirement is that the call instruction must have a debug location if the caller and callee have debug info and the call site is inlinable.
If that requirement is violated => badness.
If you can create a small test case where that happens, that'd be great.
Hm, interesting. in my repro there is a DISubprogram for the middle function, but the function itself has no dbg attachments. Maybe that is the underlying unexpected thing?
There shouldn't be a DISubprogram for 'middle' then - so I'm not sure what the Verifier's visiting.
Perhaps it visited the instructions of 'middle' even though there was no DISubprogram - then compared the Function on the DISubprogram it reached from the instructions' debuglocs to the function the instructions were in and failed? That would be a bug in the verifier - it shouldn't inspect functions without DISubprograms.
Thanks for the tips. The actual functions are reasonably well reduced, i'll try bisecting down the CUs and see what I can come up with. If that fails i'll go back to the source.
@David: When the inner function gets inlined into middle, its instructions keep their debug info.
another tip, once auto-reduction has stopped (& you've done all the obvious things that auto-reduction can't do - stripping templates and the like is one of the big ones creduce is still not very good at) you can try using alwaysinline attributes to force the inlining that the optimizer is doing anyway - then you can sometimes get back to an -O0 reproduction, jsut forcing the problematic inlining explicitly that way
I have attached a reproducer which is reduced by bugpoint; bugpoint did a pretty good job reducing the code but did nothing to the debug info, which is still huge, so I'm looking for some suggestions for making that smaller. I tried removing the !llvm.dbg.cu from the module; this had mostly the effect I was looking for, in causing most of the metadata to go away, but it also caused the problem to no longer reproduce.
Any suggestions?
Here's the rough algorithm I use.
This is often good enough. But if I really just have bitcode (e.g., from a crash in a huge LTO) or the repro is still large, I continue:
subprograms:
array, bisect which ones are necessary.(Any time you make progress, you can round-trip to bitcode to garbage collect unreferenced metadata.)
Derek - you describe the module verifier visiting the DISubprogram for the middle function. Yet you described the middle function as not having debug info. What's the deal there?
File is too bug to upload. get it at https://drive.google.com/file/d/0B_T-_5p_VNCtMmYwZG90eWpWU0k/view?usp=sharing
@llvm/issue-subscribers-debuginfo
Extended Description
I have an IR file with an approximate structure as follows. It has an inner and outer function with debug info and a middle function without debug info. The inner is inlined into the middle, and then the middle is inlined into the outer. After inlining when the module verifier visits the DISubprogram for the middle function, it checks the first instruction in middle (which originally came from inner), gets the inlinedAtScope, finds that it points to inner, and fails verification.
; Function Attrs: nounwind uwtable define void @inner() #0 { entry: