debug info "ref" parameter

I want to emit a ref parameter (ie i32*) as if it was i32 in debug info, however when I emit it with llvm.debug.declare referring to the parameter register it shows the actual pointer value of the debug register, instead of the value it refers to. This works fine if the llvm.debug.declare points to a local alloca, how can this be and how can I make it work so both show the integer value directly?

define void @test1(i32) #0 !dbg !5 {
BasicBlock0:
   %1 = alloca i32
   store i32 %0, i32* %1
   call void @llvm.dbg.declare(metadata i32* %1, metadata !20, metadata !22), !dbg !23
// This one is fine
   %2 = load i32, i32* %1, !dbg !24
   %3 = add i32 %2, 1, !dbg !24
   store i32 %3, i32* %1, !dbg !24
   ret void, !dbg !25
}

define void @ms_t1a_issuedebugouttest.__Global4_MEH2n_o_i32(i32*) #0 !dbg !9 {
BasicBlock3:
   call void @llvm.dbg.declare(metadata i32* %0, metadata !26, metadata !22), !dbg !28
   %1 = load i32, i32* %0, !dbg !29
   %2 = add i32 %1, 1, !dbg !29
   store i32 %2, i32* %0, !dbg !29
   ret void, !dbg !30
}

!22 = !DIExpression()

!20 = !DILocalVariable(name: "i", scope: !21, file: !6, line: 11, type: !13)
!26 = !DILocalVariable(name: "i", scope: !27, file: !6, line: 15, type: !13)

!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "Integer", scope: !2, file: !3, baseType: !14)
!14 = !DIBasicType(name: "Integer", size: 32, align: 32, encoding: DW_ATE_signed)

Could you provide the complete example (with all the necessary metadata to reproduce)?

Possible LLVM has a special case for arguments, I’m not sure/don’t recall off hand, but can poke around at it & see if there’s a reasonable logic to it.

https://gist.github.com/carlokok/77010598f81e8167592e593ec6c715a1

If needed I can strip it down more tomorrow, but only elements entry point and the two meh methods are used.

if you could simplify it down a bit, that might be helpful - not sure there’s a lot to be gained - I imagine it is just a quirk of how we handle these things in the backend to make normal debug info work, but there might be some things to be done to help.

That's my guess too, special behavior when it sees an alloca.
Here's a simplified version, works on i386 windows and linux (most likely 64bits too but i don't have that handy to test)

in gdb a break Test1; break Test2; run; step; locals (fine for Test1); run; step; (broken for Test2)
https://gist.github.com/carlokok/202961f81bbcf1a28139eae1d6fbf1ca

I think probably the simplest answer is that dbg.declare documents that it must point to an alloca ("This intrinsic provides information about a local element (e.g., variable). The first argument is metadata holding the alloca for the variable. ") - so it’s probably best not to think too hard about what it does when that criteria is not met. http://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare

Adrian: Another thing to check for in the debug info verifier?

Carlo: You may want/need to use a llvm.dbg.value instead.

  • Dave

I think probably the simplest answer is that dbg.declare documents that it must point to an alloca ("This intrinsic provides information about a local element (e.g., variable). The first argument is metadata holding the alloca for the variable. ") - so it's probably best not to think too hard about what it does when that criteria is not met. http://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare

Adrian: Another thing to check for in the debug info verifier?

[Sorry, I missed this thread.]
So far I avoided adding this as a check because I expected us to retire dbg.declare in the "near future" :-p

The current state of things is that llvm.dbg.declare pointing to an alloca is the only *supported* use of it. That said, I have seen declares pointing to other values in the wild (i.e. generated by clang) before, and apparently there are some combinations that do work, but they do so by accident and not by design.

Carlo: You may want/need to use a llvm.dbg.value instead.

The two options you have are:
- describe the alloca with a dbg.declare (will be valid for the entire scope of the variable)
  This is how clang describes variables at -O0.
- describe each SSA value the variable assumes with a dbg.value
  The Swift and Julia frontends do this even for unoptimized code.

-- adrian