[llvm-bugs] [Bug 40587] New: EmitFuncArgumentDbgValue hoists DBG_VALUE instructions too aggressively (or rather too often)

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Feb 4 07:16:48 PST 2019


https://bugs.llvm.org/show_bug.cgi?id=40587

            Bug ID: 40587
           Summary: EmitFuncArgumentDbgValue hoists DBG_VALUE instructions
                    too aggressively (or rather too often)
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Keywords: wrong-debug
          Severity: enhancement
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: bjorn.a.pettersson at ericsson.com
                CC: david.stenberg at ericsson.com,
                    jeremy.morse.llvm at gmail.com, llvm-bugs at lists.llvm.org

Created attachment 21428
  --> https://bugs.llvm.org/attachment.cgi?id=21428&action=edit
current result on trunk (faulty)

The usage of SelectionDAGBuilder::EmitFuncArgumentDbgValue() seems to sometime
result in incorrect hoisting of dbg.value intrinsics to the top of the entry
block. The function checks if the debug intrinsic's value is an argument, and
if so, creates a DBG_VALUE instruction and adds it to FuncInfo.ArgDbgValues,
which later results in the DBG_VALUE being emitted at the top of the entry
block. It does all this without taking any concern if the described DIVariable
itself is an argument.

Consider this example:

-------------------------------------------------
extern void bar(int);

void foo_local(int a) {
  int local = 123;
  bar(local);
  local = a;
  bar(local);
}

void foo_other_param(int a, int b) {
  bar(b);
  b = 123;
  bar(b);
  b = a;
  bar(b);
}

void foo_same_param(int a) {
  bar(a);
  int tmp = a;
  a = 123;
  bar(a);
  a = tmp;
  bar(a);
}
-------------------------------------------------

If I compiler the above using 
  clang -g -O1 -S -mllvm -stop-before=expand-isel-pseudos

I get output as in "faulty.mir", whereas I'd like to get something similar to
"wanted.mir" (see attachments).

The interesting diff between those mir files is shown here (faulty to the left,
wanted to the right) (also attached as "diff.txt") :

--- |                                                                          
                        --- |
  ; ModuleID = 'foo.c'                                                         
                          ; ModuleID = 'foo.c'
  source_filename = "foo.c"                                                    
                          source_filename = "foo.c"
  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"                  
                          target datalayout =
"e-m:e-i64:64-f80:128-n8:16:32:64-S128"
  target triple = "x86_64-unknown-linux-gnu"                                   
                          target triple = "x86_64-unknown-linux-gnu"

  ; Function Attrs: nounwind uwtable                                           
                          ; Function Attrs: nounwind uwtable
  define dso_local void @foo_local(i32 %a) local_unnamed_addr #0 !dbg !7 {     
                          define dso_local void @foo_local(i32 %a)
local_unnamed_addr #0 !dbg !7 {
  entry:                                                                       
                          entry:
    call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata
!DIExpression()), !dbg !14            call void @llvm.dbg.value(metadata i32
%a, metadata !12, metadata !DIExpression()), !dbg !14
    call void @llvm.dbg.value(metadata i32 123, metadata !13, metadata
!DIExpression()), !dbg !1            call void @llvm.dbg.value(metadata i32
123, metadata !13, metadata !DIExpression()), !dbg !1
    tail call void @bar(i32 123) #3, !dbg !16                                  
                            tail call void @bar(i32 123) #3, !dbg !16
    call void @llvm.dbg.value(metadata i32 %a, metadata !13, metadata
!DIExpression()), !dbg !15            call void @llvm.dbg.value(metadata i32
%a, metadata !13, metadata !DIExpression()), !dbg !15
    tail call void @bar(i32 %a) #3, !dbg !17                                   
                            tail call void @bar(i32 %a) #3, !dbg !17
    ret void, !dbg !18                                                         
                            ret void, !dbg !18
  }                                                                            
                          }

  declare dso_local void @bar(i32) local_unnamed_addr #1                       
                          declare dso_local void @bar(i32) local_unnamed_addr
#1

  ; Function Attrs: nounwind uwtable                                           
                          ; Function Attrs: nounwind uwtable
  define dso_local void @foo_other_param(i32 %a, i32 %b) local_unnamed_addr #0
!dbg !19 {                 define dso_local void @foo_other_param(i32 %a, i32
%b) local_unnamed_addr #0 !dbg !19 {
  entry:                                                                       
                          entry:
    call void @llvm.dbg.value(metadata i32 %a, metadata !23, metadata
!DIExpression()), !dbg !25            call void @llvm.dbg.value(metadata i32
%a, metadata !23, metadata !DIExpression()), !dbg !25
    call void @llvm.dbg.value(metadata i32 %b, metadata !24, metadata
!DIExpression()), !dbg !26            call void @llvm.dbg.value(metadata i32
%b, metadata !24, metadata !DIExpression()), !dbg !26
    tail call void @bar(i32 %b) #3, !dbg !27                                   
                            tail call void @bar(i32 %b) #3, !dbg !27
    call void @llvm.dbg.value(metadata i32 123, metadata !24, metadata
!DIExpression()), !dbg !2            call void @llvm.dbg.value(metadata i32
123, metadata !24, metadata !DIExpression()), !dbg !2
    tail call void @bar(i32 123) #3, !dbg !28                                  
                            tail call void @bar(i32 123) #3, !dbg !28
    call void @llvm.dbg.value(metadata i32 %a, metadata !24, metadata
!DIExpression()), !dbg !26            call void @llvm.dbg.value(metadata i32
%a, metadata !24, metadata !DIExpression()), !dbg !26
    tail call void @bar(i32 %a) #3, !dbg !29                                   
                            tail call void @bar(i32 %a) #3, !dbg !29
    ret void, !dbg !30                                                         
                            ret void, !dbg !30
  }                                                                            
                          }

  ; Function Attrs: nounwind uwtable                                           
                          ; Function Attrs: nounwind uwtable
  define dso_local void @foo_same_param(i32 %a) local_unnamed_addr #0 !dbg !31
{                          define dso_local void @foo_same_param(i32 %a)
local_unnamed_addr #0 !dbg !31 {
  entry:                                                                       
                          entry:
    call void @llvm.dbg.value(metadata i32 %a, metadata !33, metadata
!DIExpression()), !dbg !35            call void @llvm.dbg.value(metadata i32
%a, metadata !33, metadata !DIExpression()), !dbg !35
    tail call void @bar(i32 %a) #3, !dbg !36                                   
                            tail call void @bar(i32 %a) #3, !dbg !36
    call void @llvm.dbg.value(metadata i32 %a, metadata !34, metadata
!DIExpression()), !dbg !37            call void @llvm.dbg.value(metadata i32
%a, metadata !34, metadata !DIExpression()), !dbg !37
    call void @llvm.dbg.value(metadata i32 123, metadata !33, metadata
!DIExpression()), !dbg !3            call void @llvm.dbg.value(metadata i32
123, metadata !33, metadata !DIExpression()), !dbg !3
    tail call void @bar(i32 123) #3, !dbg !38                                  
                            tail call void @bar(i32 123) #3, !dbg !38
    call void @llvm.dbg.value(metadata i32 %a, metadata !33, metadata
!DIExpression()), !dbg !35            call void @llvm.dbg.value(metadata i32
%a, metadata !33, metadata !DIExpression()), !dbg !35
    tail call void @bar(i32 %a) #3, !dbg !39                                   
                            tail call void @bar(i32 %a) #3, !dbg !39
    ret void, !dbg !40                                                         
                            ret void, !dbg !40
  }                                                                            
                          }

...                                                                            
                        ...
---                                                                            
                        ---
name:            foo_local                                                     
                        name:            foo_local
body:             |                                                            
                        body:             |
  bb.0.entry:                                                                  
                          bb.0.entry:
    liveins: $edi                                                              
                            liveins: $edi

    DBG_VALUE $edi, $noreg, !12, !DIExpression(), debug-location !14           
                            DBG_VALUE $edi, $noreg, !12, !DIExpression(),
debug-location !14
    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !15           
                   <
    %0:gr32 = COPY $edi                                                        
                            %0:gr32 = COPY $edi
    DBG_VALUE %0, $noreg, !12, !DIExpression(), debug-location !14             
                            DBG_VALUE %0, $noreg, !12, !DIExpression(),
debug-location !14
    DBG_VALUE %0, $noreg, !13, !DIExpression(), debug-location !15             
                   <
    DBG_VALUE 123, $noreg, !13, !DIExpression(), debug-location !15            
                            DBG_VALUE 123, $noreg, !13, !DIExpression(),
debug-location !15
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead
$eflags, implicit-def             ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead
$rsp, implicit-def dead $eflags, implicit-def
    %1:gr32 = MOV32ri 123                                                      
                            %1:gr32 = MOV32ri 123
    $edi = COPY %1, debug-location !16                                         
                            $edi = COPY %1, debug-location !16
    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
implicit-def $rsp,             CALL64pcrel32 @bar, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, implicit-def $rsp,
    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags,
implicit-def dead             ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp,
implicit-def dead $eflags, implicit-def dead
                                                                               
                   >        DBG_VALUE %0, $noreg, !13, !DIExpression(),
debug-location !15
    $edi = COPY %0, debug-location !17                                         
                            $edi = COPY %0, debug-location !17
    DBG_VALUE $edi, $noreg, !12, !DIExpression(), debug-location !14           
                            DBG_VALUE $edi, $noreg, !12, !DIExpression(),
debug-location !14
    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !15           
                   <
    TCRETURNdi64 @bar, 0, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
debug-location !1            TCRETURNdi64 @bar, 0, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, debug-location !1

...                                                                            
                        ...
---                                                                            
                        ---
name:            foo_other_param                                               
                        name:            foo_other_param
body:             |                                                            
                        body:             |
  bb.0.entry:                                                                  
                          bb.0.entry:
    liveins: $edi, $esi                                                        
                            liveins: $edi, $esi

    DBG_VALUE $edi, $noreg, !23, !DIExpression(), debug-location !25           
                            DBG_VALUE $edi, $noreg, !23, !DIExpression(),
debug-location !25
    DBG_VALUE $esi, $noreg, !24, !DIExpression(), debug-location !26           
                            DBG_VALUE $esi, $noreg, !24, !DIExpression(),
debug-location !26
    DBG_VALUE $edi, $noreg, !24, !DIExpression(), debug-location !26           
                   <
    %1:gr32 = COPY $esi                                                        
                            %1:gr32 = COPY $esi
    DBG_VALUE %1, $noreg, !24, !DIExpression(), debug-location !26             
                            DBG_VALUE %1, $noreg, !24, !DIExpression(),
debug-location !26
    %0:gr32 = COPY $edi                                                        
                            %0:gr32 = COPY $edi
    DBG_VALUE %0, $noreg, !23, !DIExpression(), debug-location !25             
                            DBG_VALUE %0, $noreg, !23, !DIExpression(),
debug-location !25
    DBG_VALUE %0, $noreg, !24, !DIExpression(), debug-location !26             
                   <
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead
$eflags, implicit-def             ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead
$rsp, implicit-def dead $eflags, implicit-def
    $edi = COPY %1, debug-location !27                                         
                            $edi = COPY %1, debug-location !27
    DBG_VALUE $edi, $noreg, !24, !DIExpression(), debug-location !26           
                            DBG_VALUE $edi, $noreg, !24, !DIExpression(),
debug-location !26
    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
implicit-def $rsp,             CALL64pcrel32 @bar, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, implicit-def $rsp,
    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags,
implicit-def dead             ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp,
implicit-def dead $eflags, implicit-def dead
    DBG_VALUE 123, $noreg, !24, !DIExpression(), debug-location !26            
                            DBG_VALUE 123, $noreg, !24, !DIExpression(),
debug-location !26
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead
$eflags, implicit-def             ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead
$rsp, implicit-def dead $eflags, implicit-def
    %2:gr32 = MOV32ri 123                                                      
                            %2:gr32 = MOV32ri 123
    $edi = COPY %2, debug-location !28                                         
                            $edi = COPY %2, debug-location !28
    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
implicit-def $rsp,             CALL64pcrel32 @bar, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, implicit-def $rsp,
    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags,
implicit-def dead             ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp,
implicit-def dead $eflags, implicit-def dead
                                                                               
                   >        DBG_VALUE %0, $noreg, !24, !DIExpression(),
debug-location !26
    $edi = COPY %0, debug-location !29                                         
                            $edi = COPY %0, debug-location !29
    DBG_VALUE $edi, $noreg, !23, !DIExpression(), debug-location !25           
                            DBG_VALUE $edi, $noreg, !23, !DIExpression(),
debug-location !25
    DBG_VALUE $edi, $noreg, !24, !DIExpression(), debug-location !26           
                   <
    TCRETURNdi64 @bar, 0, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
debug-location !2            TCRETURNdi64 @bar, 0, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, debug-location !2

...                                                                            
                        ...
---                                                                            
                        ---
name:            foo_same_param                                                
                        name:            foo_same_param
body:             |                                                            
                        body:             |
  bb.0.entry:                                                                  
                          bb.0.entry:
    liveins: $edi                                                              
                            liveins: $edi

    DBG_VALUE $edi, $noreg, !33, !DIExpression(), debug-location !35           
                            DBG_VALUE $edi, $noreg, !33, !DIExpression(),
debug-location !35
    DBG_VALUE $edi, $noreg, !34, !DIExpression(), debug-location !37           
                   <
    DBG_VALUE $edi, $noreg, !33, !DIExpression(), debug-location !35           
                   <
    %0:gr32 = COPY $edi                                                        
                            %0:gr32 = COPY $edi
    DBG_VALUE %0, $noreg, !33, !DIExpression(), debug-location !35             
                            DBG_VALUE %0, $noreg, !33, !DIExpression(),
debug-location !35
    DBG_VALUE %0, $noreg, !34, !DIExpression(), debug-location !37             
                   <
    DBG_VALUE %0, $noreg, !33, !DIExpression(), debug-location !35             
                   <
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead
$eflags, implicit-def             ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead
$rsp, implicit-def dead $eflags, implicit-def
    $edi = COPY %0, debug-location !36                                         
                            $edi = COPY %0, debug-location !36
    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
implicit-def $rsp,             CALL64pcrel32 @bar, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, implicit-def $rsp,
    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags,
implicit-def dead             ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp,
implicit-def dead $eflags, implicit-def dead
                                                                               
                   >        DBG_VALUE %0, $noreg, !34, !DIExpression(),
debug-location !37
    DBG_VALUE 123, $noreg, !33, !DIExpression(), debug-location !35            
                            DBG_VALUE 123, $noreg, !33, !DIExpression(),
debug-location !35
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead
$eflags, implicit-def             ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead
$rsp, implicit-def dead $eflags, implicit-def
    %1:gr32 = MOV32ri 123                                                      
                            %1:gr32 = MOV32ri 123
    $edi = COPY %1, debug-location !38                                         
                            $edi = COPY %1, debug-location !38
    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
implicit-def $rsp,             CALL64pcrel32 @bar, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, implicit-def $rsp,
    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags,
implicit-def dead             ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp,
implicit-def dead $eflags, implicit-def dead
                                                                               
                   >        DBG_VALUE %0, $noreg, !33, !DIExpression(),
debug-location !35
    $edi = COPY %0, debug-location !39                                         
                            $edi = COPY %0, debug-location !39
    TCRETURNdi64 @bar, 0, csr_64, implicit $rsp, implicit $ssp, implicit $edi,
debug-location !3            TCRETURNdi64 @bar, 0, csr_64, implicit $rsp,
implicit $ssp, implicit $edi, debug-location !3

...                                                                            
                        ...


As seen, the usage of FuncInfo.ArgDbgValues has incorrectly hoisted lots of
DBG_VALUE nodes to the top of the entry block .

One could question if we should use FuncInfo.ArgDbgValues at all for dbg.value
(why are we treating functions args differently from any other value). It seems
like we need it to be able to get debug ranges for the input arguments early in
the function (typically already inside the prologue). Anyway, today we use
FuncInfo.ArgDbgValues too often, and I think
SelectionDAGBuilder::EmitFuncArgumentDbgValue() needs to be more careful about
when to use FuncInfo.ArgDbgValues.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190204/58efe864/attachment-0001.html>


More information about the llvm-bugs mailing list