[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