<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 12 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Cambria;
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
h1
{mso-style-priority:9;
mso-style-link:"Heading 1 Char";
margin-top:24.0pt;
margin-right:0cm;
margin-bottom:0cm;
margin-left:0cm;
margin-bottom:.0001pt;
page-break-after:avoid;
font-size:14.0pt;
font-family:"Cambria","serif";
color:#365F91;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:36.0pt;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
span.Heading1Char
{mso-style-name:"Heading 1 Char";
mso-style-priority:9;
mso-style-link:"Heading 1";
font-family:"Cambria","serif";
color:#365F91;
font-weight:bold;}
span.EmailStyle19
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:138764634;
mso-list-type:hybrid;
mso-list-template-ids:-682575134 1205371834 134807555 134807557 134807553 134807555 134807557 134807553 134807555 134807557;}
@list l0:level1
{mso-level-start-at:9;
mso-level-number-format:bullet;
mso-level-text:-;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-18.0pt;
font-family:"Calibri","sans-serif";
mso-fareast-font-family:Calibri;
mso-bidi-font-family:"Times New Roman";}
@list l0:level2
{mso-level-tab-stop:72.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level3
{mso-level-tab-stop:108.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level4
{mso-level-tab-stop:144.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level5
{mso-level-tab-stop:180.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level6
{mso-level-tab-stop:216.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level7
{mso-level-tab-stop:252.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level8
{mso-level-tab-stop:288.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level9
{mso-level-tab-stop:324.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">I have been investigating missing variables / incorrect variable values when debugging code compiled at –O1 (and above) and believe that I have tracked the issue down to the interaction of the generation of IR @llvm.dbg.value entries and
phi nodes. I would welcome someone who is more familiar with the generation of debug information to help me determine if what I think is going wrong is correct and guidance on the best/correct way of fixing the issue.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">[I was using the ARM and AArch64 targets in my investigation, but I believe that this issue is target independent]<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The following simple C code reproducer:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">int func(int a)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> int c = 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> if (a < 0 ) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> c = 2;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> }<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> return c;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Generates the following IR when compiling at –O0<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">define i32 @func(i32 %a) #0 !dbg !8 {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">entry:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %a.addr = alloca i32, align 4<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %c = alloca i32, align 4<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> store i32 %a, i32* %a.addr, align 4<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !12, metadata !13), !dbg !14<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.declare(metadata i32* %c, metadata !15, metadata !13), !dbg !16<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> store i32 1, i32* %c, align 4, !dbg !16<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %0 = load i32, i32* %a.addr, align 4, !dbg !17<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %cmp = icmp slt i32 %0, 0, !dbg !19<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> br i1 %cmp, label %if.then, label %if.end, !dbg !20<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">if.then: ; preds = %entry<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> store i32 2, i32* %c, align 4, !dbg !21<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> br label %if.end, !dbg !23<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">if.end: ; preds = %if.then, %entry<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %1 = load i32, i32* %c, align 4, !dbg !24<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ret i32 %1, !dbg !25<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This generates sensible DWARF location information for the variable c. So debugging the code compiled at –O0 is just fine .... looking at the value of c when on the return statement the correct value is returned.<br>
<br>
However if I pass this IR through the –mem2reg optimisation phase, the debug information for the variable C becomes incorrect for the return statement:<br>
<br>
<span style="font-family:"Courier New"">define i32 @func(i32 %a) #0 !dbg !8 {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">entry:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !12, metadata !13), !dbg !14<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 1, i64 0, metadata !15, metadata !13), !dbg !16<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %cmp = icmp slt i32 %a, 0, !dbg !17<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> br i1 %cmp, label %if.then, label %if.end, !dbg !19<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">if.then: ; preds = %entry<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 2, i64 0, metadata !15, metadata !13), !dbg !16<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> br label %if.end, !dbg !20<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">if.end: ; preds = %if.then, %entry<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %c.0 = phi i32 [ 2, %if.then ], [ 1, %entry ]<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ret i32 %c.0, !dbg !22<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The value of the variable c when on the return statement is always incorrectly reported as being the value 2. The generated DWARF location list for the variable c looks something like (the offset 00000038 is beyond the end of the function):<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> 00000013 00000004 00000024 (DW_OP_consts: 1; DW_OP_stack_value)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> 00000020 00000024 00000038 (DW_OP_consts: 2; DW_OP_stack_value)<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
I know what is wrong, I thought! After the phi instruction there should be an @llvm.dbg.value call which describes the variable c as having the value returned by the phi, so I manually altered the IR to the following, thinking that the return statement would
now be able to generate the correct location information for the variable c:<o:p></o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">define i32 @func(i32 %a) #0 !dbg !8 {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">entry:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !12, metadata !13), !dbg !14<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 1, i64 0, metadata !15, metadata !13), !dbg !16<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %cmp = icmp slt i32 %a, 0, !dbg !17<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> br i1 %cmp, label %if.then, label %if.end, !dbg !19<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">if.then: ; preds = %entry<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 2, i64 0, metadata !15, metadata !13), !dbg !16<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> br label %if.end, !dbg !20<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">if.end: ; preds = %if.then, %entry<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> %c.0 = phi i32 [ 2, %if.then ], [ 1, %entry ]<o:p></o:p></span></p>
<p class="MsoNormal"><b><span style="font-family:"Courier New""> call void @llvm.dbg.value(metadata i32 %c.0, i64 0, metadata !15, metadata !13), !dbg !16<o:p></o:p></span></b></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ret i32 %c.0, !dbg !22<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Unfortunately adding this additional line makes no difference to the generated debug information, and the value of the variable c is still incorrectly reported to be 2 when on the return statement.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">So my question is whether:<o:p></o:p></p>
<p class="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"><![if !supportLists]><span style="mso-list:Ignore">-<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]>The above addition to the IR is the correct thing to do [but if so then there is possibly a further issue in SelectionDAGBuilder::visitIntrinsicCall()’s handling of this additional line (where it is currently being discarded)]<o:p></o:p></p>
<p class="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo2"><![if !supportLists]><span style="mso-list:Ignore">-<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]>Some other @lldm.dbg.value entry should be produced to generate the correct debug information.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Keith<o:p></o:p></p>
</div>
</body>
</html>