[llvm-dev] IR @llvm.dbg.value entries for variables when a phi node has been created
Keith Walker via llvm-dev
llvm-dev at lists.llvm.org
Fri Jul 29 12:26:45 PDT 2016
I have been investigating missing variables / incorrect variable values when debugging code compiled at -O1 (and above) and believe that I have tracked the issue down to the interaction of the generation of IR @llvm.dbg.value entries and phi nodes. I would welcome someone who is more familiar with the generation of debug information to help me determine if what I think is going wrong is correct and guidance on the best/correct way of fixing the issue.
[I was using the ARM and AArch64 targets in my investigation, but I believe that this issue is target independent]
The following simple C code reproducer:
int func(int a)
{
int c = 1;
if (a < 0 ) {
c = 2;
}
return c;
}
Generates the following IR when compiling at -O0
define i32 @func(i32 %a) #0 !dbg !8 {
entry:
%a.addr = alloca i32, align 4
%c = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !12, metadata !13), !dbg !14
call void @llvm.dbg.declare(metadata i32* %c, metadata !15, metadata !13), !dbg !16
store i32 1, i32* %c, align 4, !dbg !16
%0 = load i32, i32* %a.addr, align 4, !dbg !17
%cmp = icmp slt i32 %0, 0, !dbg !19
br i1 %cmp, label %if.then, label %if.end, !dbg !20
if.then: ; preds = %entry
store i32 2, i32* %c, align 4, !dbg !21
br label %if.end, !dbg !23
if.end: ; preds = %if.then, %entry
%1 = load i32, i32* %c, align 4, !dbg !24
ret i32 %1, !dbg !25
}
This generates sensible DWARF location information for the variable c. So debugging the code compiled at -O0 is just fine .... looking at the value of c when on the return statement the correct value is returned.
However if I pass this IR through the -mem2reg optimisation phase, the debug information for the variable C becomes incorrect for the return statement:
define i32 @func(i32 %a) #0 !dbg !8 {
entry:
call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !12, metadata !13), !dbg !14
call void @llvm.dbg.value(metadata i32 1, i64 0, metadata !15, metadata !13), !dbg !16
%cmp = icmp slt i32 %a, 0, !dbg !17
br i1 %cmp, label %if.then, label %if.end, !dbg !19
if.then: ; preds = %entry
call void @llvm.dbg.value(metadata i32 2, i64 0, metadata !15, metadata !13), !dbg !16
br label %if.end, !dbg !20
if.end: ; preds = %if.then, %entry
%c.0 = phi i32 [ 2, %if.then ], [ 1, %entry ]
ret i32 %c.0, !dbg !22
}
The value of the variable c when on the return statement is always incorrectly reported as being the value 2. The generated DWARF location list for the variable c looks something like (the offset 00000038 is beyond the end of the function):
00000013 00000004 00000024 (DW_OP_consts: 1; DW_OP_stack_value)
00000020 00000024 00000038 (DW_OP_consts: 2; DW_OP_stack_value)
I know what is wrong, I thought! After the phi instruction there should be an @llvm.dbg.value call which describes the variable c as having the value returned by the phi, so I manually altered the IR to the following, thinking that the return statement would now be able to generate the correct location information for the variable c:
define i32 @func(i32 %a) #0 !dbg !8 {
entry:
call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !12, metadata !13), !dbg !14
call void @llvm.dbg.value(metadata i32 1, i64 0, metadata !15, metadata !13), !dbg !16
%cmp = icmp slt i32 %a, 0, !dbg !17
br i1 %cmp, label %if.then, label %if.end, !dbg !19
if.then: ; preds = %entry
call void @llvm.dbg.value(metadata i32 2, i64 0, metadata !15, metadata !13), !dbg !16
br label %if.end, !dbg !20
if.end: ; preds = %if.then, %entry
%c.0 = phi i32 [ 2, %if.then ], [ 1, %entry ]
call void @llvm.dbg.value(metadata i32 %c.0, i64 0, metadata !15, metadata !13), !dbg !16
ret i32 %c.0, !dbg !22
}
Unfortunately adding this additional line makes no difference to the generated debug information, and the value of the variable c is still incorrectly reported to be 2 when on the return statement.
So my question is whether:
- The above addition to the IR is the correct thing to do [but if so then there is possibly a further issue in SelectionDAGBuilder::visitIntrinsicCall()'s handling of this additional line (where it is currently being discarded)]
- Some other @lldm.dbg.value entry should be produced to generate the correct debug information.
Keith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160729/baaf3dc2/attachment.html>
More information about the llvm-dev
mailing list