'LowerDbgDeclare' in Instruction combining affects scope information

Hi All,

For the test snippet below,
int func(int dd, int ds, int *rm)
{
int d_sn = 0;
int dv_sn = 0;
unsigned int d, r;
if (dd < 0) { d_sn = 1; dd = -dd; };
if (ds < 0) { dv_sn = 1; ds = -ds ; };

d = func1( dd, ds, &r);

if (d_sn && dv_sn){ r = -r;}
else if (d_sn) { d = -d; r = -r; }
else if (dv_sn) { d = -d; };

if (rm) { *rm = (signed int)r; }
return (signed int)d;
}

My observations for the generated .ll are (I am using llvm3.1):

  1. Due to ‘instruction combining’ optimization which does ‘LowerDbgDeclare’ call, I get a lot of ‘llvm.dbg.value’ instruction for r inserted, which converts ‘load with llvm.dbg.declare’ to addition of llvm.dbg.value. Is it ok to get such a behavior or I am wrong in my analysis? Please correct me.

  2. I referred a link below, which talks of a patch provided for such a behavior.
    http://permalink.gmane.org/gmane.comp.compilers.llvm.cvs/142570
    Can I get access to the patch to try on my test ? Or is it concerned with something different?

  3. The implication of this behavior is that when I try to get the lexicalscope for variable r, it shows be 4 declaration of ‘variable r’ in the parent scope. I am expect only 1 declaration. I feel the addition of dbg.declare in other basic blocks is leading to this.

Generated .ll :
define i32 @func(i32 %dd, i32 %ds, i32* %rm) nounwind {
entry:
%r = alloca i32, align 4
call void @llvm.dbg.value(metadata !{i32 %dd}, i64 0, metadata !13), !dbg !14
call void @llvm.dbg.value(metadata !{i32 %ds}, i64 0, metadata !15), !dbg !16
call void @llvm.dbg.value(metadata !{i32* %rm}, i64 0, metadata !17), !dbg !18
call void @llvm.dbg.value(metadata !2, i64 0, metadata !19), !dbg !21
call void @llvm.dbg.value(metadata !2, i64 0, metadata !22), !dbg !23
call void @llvm.dbg.declare(metadata !{i32* %r}, metadata !24), !dbg !26
%cmp = icmp slt i32 %dd, 0, !dbg !27
%sub = sub nsw i32 0, %dd, !dbg !28
%sub.dd = select i1 %cmp, i32 %sub, i32 %dd, !dbg !27
%cmp1 = icmp slt i32 %ds, 0, !dbg !30
call void @llvm.dbg.value(metadata !31, i64 0, metadata !22), !dbg !32
%sub3 = sub nsw i32 0, %ds, !dbg !34
call void @llvm.dbg.value(metadata !{i32 %sub3}, i64 0, metadata !15), !dbg !34
%ds.addr.0 = select i1 %cmp1, i32 %sub3, i32 %ds, !dbg !30
%call = call i32 bitcast (i32 (…)* @func1 to i32 (i32, i32, i32*))(i32 %sub.dd, i32 %ds.addr.0, i32 %r) nounwind, !dbg !
call void @llvm.dbg.value(metadata !{i32 %call}, i64 0, metadata !36), !dbg !35
%0 = and i32 %dd, %ds, !dbg !37
%1 = icmp slt i32 %0, 0, !dbg !37
br i1 %1, label %if.then6, label %if.else, !dbg !37
if.then6: ; preds = %entry
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !38
%2 = load i32* %r, align 4, !dbg !38
%sub7 = sub i32 0, %2, !dbg !38
call void @llvm.dbg.value(metadata !{i32 %sub7}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32 %sub7}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32 %sub7}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32 %sub7}, i64 0, metadata !24), !dbg !38
call void @llvm.dbg.value(metadata !{i32 %sub7}, i64 0, metadata !24), !dbg !38
store i32 %sub7, i32* %r, align 4, !dbg !38
br label %if.end18, !dbg !40
if.else: ; preds = %entry
%sub10 = sub i32 0, %call, !dbg !41
br i1 %cmp, label %if.then9, label %if.else12, !dbg !43
if.then9: ; preds = %if.else
call void @llvm.dbg.value(metadata !{i32 %sub10}, i64 0, metadata !36), !dbg !41
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !44
%3 = load i32* %r, align 4, !dbg !44
%sub11 = sub i32 0, %3, !dbg !44
call void @llvm.dbg.value(metadata !{i32 %sub11}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32 %sub11}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32 %sub11}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32 %sub11}, i64 0, metadata !24), !dbg !44
call void @llvm.dbg.value(metadata !{i32 %sub11}, i64 0, metadata !24), !dbg !44
store i32 %sub11, i32* %r, align 4, !dbg !44
br label %if.end18, !dbg !45
if.else12: ; preds = %if.else
%sub15.call = select i1 %cmp1, i32 %sub10, i32 %call, !dbg !46
br label %if.end18
if.end18: ; preds = %if.else12, %if.then9, %if.then6
%d.2 = phi i32 [ %call, %if.then6 ], [ %sub10, %if.then9 ], [ %sub15.call, %if.else12 ]
%tobool19 = icmp eq i32* %rm, null, !dbg !47
br i1 %tobool19, label %if.end21, label %if.then20, !dbg !47
if.then20: ; preds = %if.end18
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !48
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !48
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !48
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !48
call void @llvm.dbg.value(metadata !{i32* %r}, i64 0, metadata !24), !dbg !48
%4 = load i32* %r, align 4, !dbg !48
store i32 %4, i32* %rm, align 4, !dbg !48
br label %if.end21, !dbg !50
if.end21: ; preds = %if.then20, %if.end18
ret i32 %d.2, !dbg !51
}

Regards,
Pankaj