[LLVMbugs] [Bug 5726] New: Incorrrect debug info with clang and mem2reg

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Tue Dec 8 12:45:41 PST 2009


http://llvm.org/bugs/show_bug.cgi?id=5726

           Summary: Incorrrect debug info with clang and mem2reg
           Product: new-bugs
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: edwintorok at gmail.com
                CC: llvmbugs at cs.uiuc.edu


Consider this source code:
int add(int a, int b)
{
    return a + b;
}

int main()
{
    return add(5, 3);
}

There are 2 issues when using clang here:
1). the returns from the function are attributed to the line that has '}', not
to the line that has 'return '. 

One could argue that this is correct behavior. It would be IFF only the 'ret'
instruction would have the location of '}', but see 2)

2. opt -mem2reg collapses some instruction's location with the next ones (such
as call add, ret -> the call's location becomes ret's.
I think this is a bug.

The result is that after compiling with clang -O0 -g, even a simple pass like
-mem2reg causes incorrect debug info, which is confusing when trying to
single-step in the debugger.

When compiled with clang -g, the add in function main is correctly attributed
to simple.c:8:5 (see attached testcase.bc):
define i32 @main() nounwind {
entry:
  %retval = alloca i32                            ; <i32*> [#uses=3]
  store i32 0, i32* %retval
  %call = call i32 @add(i32 5, i32 3), !dbg !12   ; <i32> [#uses=1]
  store i32 %call, i32* %retval, !dbg !12
  %0 = load i32* %retval, !dbg !15                ; <i32> [#uses=1]
  ret i32 %0, !dbg !15
}

!12 = metadata !{i32 8, i32 5, metadata !13, null}
!15 = metadata !{i32 9, i32 1, metadata !14, null}

However the return is incorrectly attributed to line simple.c:9:1 (which is
just a }, not the return itself).

Now run opt -mem2reg, it will look like this:
define i32 @main() nounwind {
entry:
  %call = call i32 @add(i32 5, i32 3), !dbg !6    ; <i32> [#uses=1]
  ret i32 %call, !dbg !6
}
!6 = metadata !{i32 9, i32 1, metadata !7, null}

Thus the call to add is attributed to 9:1, whereas there is no code on that (it
is the return from function, the }). This looks awkward in a debugger:
Breakpoint 1, main () at simple.c:7
7       {
(gdb) s
9       }
(gdb) s
add () at simple.c:4
4       }

The debugger doesn't show any of the useful source lines as executing.

Compare this with gcc at -O1, which is slightly better:
Breakpoint 1, main () at examples/in/simple.c:8
8           return add(5, 3);
(gdb) s
add (a=5, b=3) at examples/in/simple.c:2
2       {
(gdb) s
add (a=5, b=3) at examples/in/simple.c:4
4       }
(gdb) s
main () at examples/in/simple.c:9
9       }

Or even with the output from llvm-gcc -O1 which is much better:
Breakpoint 1, main () at simple.c:7
7       {
(gdb) s
8           return add(5, 3);
(gdb) s
add () at simple.c:3
3           return a + b;
(gdb) s


-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list