[llvm] r235050 - DebugInfo: Remove 'inlinedAt:' field from MDLocalVariable

Duncan P. N. Exon Smith dexonsmith at apple.com
Thu Apr 16 18:03:58 PDT 2015


> On 2015-Apr-16, at 18:03, Adrian Prantl <aprantl at apple.com> wrote:
> 
>> 
>> On Apr 16, 2015, at 5:59 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>> 
>> 
>>> On 2015-Apr-16, at 17:56, Adrian Prantl <aprantl at apple.com> wrote:
>>> 
>>>> 
>>>> On Apr 16, 2015, at 5:55 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>>>> 
>>>> 
>>>>> On 2015-Apr-16, at 15:50, David Blaikie <dblaikie at gmail.com> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>> On Thu, Apr 16, 2015 at 3:37 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>>>>> 
>>>>>> On 2015-Apr-16, at 14:21, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>>>>>> 
>>>>>>> 
>>>>>>> On 2015-Apr-16, at 11:41, David Blaikie <dblaikie at gmail.com> wrote:
>>>>>>> 
>>>>>>> (from IRC discussion)
>>>>>>> 
>>>>>>> Looks like this might've caused the GDB buildbot regression seen here: http://lab.llvm.org:8011/builders/clang-x86_64-ubuntu-gdb-75/builds/21390
>>>>>>> 
>>>>>>> Specifically, in the below program
>>>>>>> 
>>>>>>> int *g;
>>>>>>> 
>>>>>>> static __attribute__((always_inline)) int f(int a) {
>>>>>>> int l;
>>>>>>> g = &l;
>>>>>>> return a;
>>>>>>> }
>>>>>>> 
>>>>>>> int main(void) {
>>>>>>> f(0);
>>>>>>> f(0);
>>>>>>> return 0;
>>>>>>> }
>>>>>>> 
>>>>>>> The inlined_subroutine for 'f' in 'main' has no DW_TAG_formal_parameter (for 'a')
>>>>>> 
>>>>>> I've tracked this down -- UserValue::match() needed to be updated.
>>>>> 
>>>>> r235140
>>>>> 
>>>>>> 
>>>>>> I fixed what might be an unrelated bug in DebugLocEntry.  I'll have
>>>>>> to separate out the two changes to see if this testcase provides any
>>>>>> coverage for `DebugLocEntry`; if not I'll maybe need some help from
>>>>>> you or Adrian coming up with a good testcase for that one.
>>>>> 
>>>>> This turned out to be unrelated.
>>>>> 
>>>>> Looking at the code, I'm not even sure what the variables are doing in
>>>>> `DebugLocEntry` -- they're only used to prevent adjacent locations from
>>>>> coalescing.  I guess the main problem is I don't know what this table is
>>>>> for (well, `.debug_loc`, but I don't know what that is either).
>>>>> 
>>>>> .debug_loc is for variables that don't reside in just a single location for their entire lifetime (much like debug_ranges discussed earlier) - if a variable resides in a single place for its entire scope, then DW_AT_location will have a dwarf expression describing that location, otherwise it'll have a sec_offset/data4 giving the offset in debug_loc that describes the various locations and ranges for the variable.
>>>>> 
>>>>> You might look for existing test cases that produce debug_loc sections? But I don't have a canonical way to produce one off-hand. I imagine if one is produced for two distinct inlined variables (from distinct inlined calls to the same function) then their location lists might end up accidentally shared (they'd end up with the same location list (possibly combining both variable location lists), rather than distinct ones)?
>>>>> 
>>>> 
>>>> I tried a variation on your simplified testcase for the original bug,
>>>> hoping that the variables would somehow be coalesced badly:
>>>> 
>>>> void sink(void);
>>>> static __attribute__((always_inline)) void bar(int a) { sink(); }
>>>> void foo(void) {
>>>>   bar(0);
>>>>   bar(1);
>>>> }
>>>> 
>>>> Unfortunately, the dwarfdump output doesn't change with my fix to
>>>> DebugLocEntry.  But I did get something weird:
>>>> 
>>>> 0x00000068:     DW_TAG_inlined_subroutine [6] *
>>>>               DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x002f => {0x0000002f} "bar")
>>>>               DW_AT_low_pc [DW_FORM_addr]	(0x0000000000000004)
>>>>               DW_AT_high_pc [DW_FORM_addr]	(0x0000000000000009)
>>>>               DW_AT_call_file [DW_FORM_data1]	("/Users/dexonsmith/data/llvm/staging/play/inlined-at/t.c")
>>>>               DW_AT_call_line [DW_FORM_data1]	(4)
>>>> 
>>>> 0x0000007f:       DW_TAG_formal_parameter [7]  
>>>>                 DW_AT_const_value [DW_FORM_sdata]	(0)
>>>>                 DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x0039 => {0x00000039} "a")
>>>> 
>>>> 0x00000085:       NULL
>>>> 
>>>> 0x00000086:     DW_TAG_inlined_subroutine [6] *
>>>>               DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x002f => {0x0000002f} "bar")
>>>>               DW_AT_low_pc [DW_FORM_addr]	(0x0000000000000009)
>>>>               DW_AT_high_pc [DW_FORM_addr]	(0x000000000000000f)
>>>>               DW_AT_call_file [DW_FORM_data1]	("/Users/dexonsmith/data/llvm/staging/play/inlined-at/t.c")
>>>>               DW_AT_call_line [DW_FORM_data1]	(5)
>>>> 
>>>> 0x0000009d:       DW_TAG_formal_parameter [7]  
>>>>                 DW_AT_const_value [DW_FORM_sdata]	(0)
>>>>                 DW_AT_abstract_origin [DW_FORM_ref4]	(cu + 0x0039 => {0x00000039} "a")
>>>> 
>>>> 0x000000a3:       NULL
>>>> 
>>>> 0x000000a4:     NULL
>>>> 
>>>> 
>>>> Notice that "a" has the same value (0) in both inlined subroutines.
>>>> 
>>>> This is *not* a regression from r235050 -- older clangs give me the
>>>> same thing here.
>>>> 
>>>> Is this a known bug?  (Or am I confused, and it's not a bug?)
>>> 
>>> If the IR shows two different dbg.value intrinsics (and it should!) this is definitely a bug.
>>> 
>>> -- adrian
>> 
>> Right, check the IR.  The IR is wrong.
>> 
>> Old IR (pre r235050):
>> 
>> define void @foo() #0 {
>> entry:
>> tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !19) #3, !dbg !20
>> tail call void @sink() #3, !dbg !21
>> tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !22, metadata !19) #3, !dbg !24
>> tail call void @sink() #3, !dbg !25
>> ret void, !dbg !26
>> }
>> 
>> New IR (post):
>> 
>> define void @foo() #0 {
>> entry:
>> tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !12, metadata !17) #3, !dbg !18
>> tail call void @sink() #3, !dbg !20
>> tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !12, metadata !17) #3, !dbg !21
> 
> The fact that both are !12 now is because the inlinedAt attribute moved into the DebugLoc, right?

Yup.  Well, it was already there, but it disappeared from the variable.

> 
>> tail call void @sink() #3, !dbg !23
>> ret void, !dbg !24
>> }
>> 
>> In both cases, there are two `@llvm.dbg.value()` intrinsics, but they're
>> incorrectly both pointing at `i32 0`.  One should be `i32 1`, right?
> 
> Could you file a PR for this?

Will do.

This happens during dead argument elimination BTW.

*** IR Dump After Dead Argument Elimination ***; ModuleID = 't.c'
; Function Attrs: alwaysinline nounwind ssp uwtable
define internal fastcc void @bar() #1 {
entry:
  call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !12, metadata !20), !dbg !21
  call void @sink(), !dbg !22
  ret void, !dbg !23
}


> 
> -- adrian
> 
>> 
>>> 
>>>> 
>>>>> 
>>>>> By inspection, r235050 caused a behaviour change here (and the attached
>>>>> patch would revert the behaviour change), but I honestly have no idea
>>>>> what to test.
>>>>> 
>>>>> Adrian, you seem to have touched this code most recently.  Any ideas?





More information about the llvm-commits mailing list