<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 15 (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: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;
        mso-fareast-language:EN-US;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></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="SV" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">The Loop Strength Reduction pass appears to break debug information even for<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">the most basic input. I believe this is a well known issue already (see<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">https://bugs.llvm.org/show_bug.cgi?id=38815) but I also believe that it deserve<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">some extra attention.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Consider the following input compiled with 'clang -g -O3 foo.c -mllvm -print-after-all'<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">---<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">void foo(unsigned char *p) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">#pragma clang loop unroll(disable)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  for (unsigned char i = 0; i < 32; i++) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    p += 3;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">    *p = i;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  }<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">---<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">As can be seen below in the pre-LSR dump the pointer 'p' is desribed by<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">dbg.value both before and after it is incremented. In the post-LSR setting<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">these dbg.value are now referring to undef so the debug-info for 'p' is<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">effectively lost.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">It is interesting to note that after LSR one dbg.value has its DIExpression<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">adjusted to add the value three but it is still referring to undef. As I<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">understand it this is the work of salvageDebugInfo. When LSR has created the<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">new induction variable expression and starts deleting the old one salvaging<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">will kick in. When %add.ptr is deleted it will adjust the dbg.value use of<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">that to use the value %p.addr.05, and by doing so it must accordingly adjust the<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">DIExpression. This all works fine until the phi-node is also deleted at which<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">point there is not much that can be done with the current scheme.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">One idea for how to address this would be that, since LSR is a SCEV based<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">optimization, one could perform additional debug salvaging by comparing SCEV<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">expressions for the new and old PHI-node and then adjusting DIExpressions if<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">they match with an offset.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Any thoughts on that?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">-Markus<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">---<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">*** IR Dump After Canonicalize Freeze Instructions in Loops ***<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">; Preheader:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">entry:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8* %p, metadata <0x111daf20>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8 0, metadata <0x111dcb00>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  br label %for.body, !dbg !DILocation(line: 3, column: 3, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">; Loop:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">for.body:                                         ; preds = %entry, %for.body<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %i.06 = phi i8 [ 0, %entry ], [ %inc, %for.body ]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %p.addr.05 = phi i8* [ %p, %entry ], [ %add.ptr, %for.body ]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8 %i.06, metadata <0x111dcb00>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8* %p.addr.05, metadata <0x111daf20>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %add.ptr = getelementptr inbounds i8, i8* %p.addr.05, i64 3, !dbg !DILocation(line: 4, column: 7, scope: <0x111ddc90>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8* %add.ptr, metadata <0x111daf20>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  store i8 %i.06, i8* %add.ptr, align 1, !dbg !DILocation(line: 5, column: 8, scope: <0x111ddc90>), !tbaa <0x111dd288><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %inc = add nuw nsw i8 %i.06, 1, !dbg !DILocation(line: 3, column: 38, scope: <0x111dd510>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8 %inc, metadata <0x111dcb00>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %exitcond.not = icmp eq i8 %inc, 32, !dbg !DILocation(line: 3, column: 31, scope: <0x111dd510>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !dbg !DILocation(line: 3, column: 3, scope: <0x111dc650>), !llvm.loop <0x111de7b0><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">; Exit blocks<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">for.cond.cleanup:                                 ; preds = %for.body<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  ret void, !dbg !DILocation(line: 7, column: 1, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">*** IR Dump After Loop Strength Reduction ***<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">; Preheader:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">entry:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8* %p, metadata <0x111daf20>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"> call void @llvm.dbg.value(metadata i8 0, metadata <0x111dcb00>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %scevgep = getelementptr i8, i8* %p, i64 3, !dbg !DILocation(line: 3, column: 3, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  br label %for.body, !dbg !DILocation(line: 3, column: 3, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">; Loop:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">for.body:                                         ; preds = %entry, %for.body<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %lsr.iv = phi i8* [ %scevgep, %entry ], [ %scevgep7, %for.body ]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %i.06 = phi i8 [ 0, %entry ], [ %inc, %for.body ]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8 %i.06, metadata <0x111dcb00>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8* undef, metadata <0x111daf20>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8* undef, metadata <0x111daf20>, metadata !DIExpression(DW_OP_plus_uconst, 3, DW_OP_stack_value)), !dbg !DILocation(line: 0, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  store i8 %i.06, i8* %lsr.iv, align 1, !dbg !DILocation(line: 5, column: 8, scope: <0x111ddc90>), !tbaa <0x111dd288><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %inc = add nuw nsw i8 %i.06, 1, !dbg !DILocation(line: 3, column: 38, scope: <0x111dd510>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  call void @llvm.dbg.value(metadata i8 %inc, metadata <0x111dcb00>, metadata !DIExpression()), !dbg !DILocation(line: 0, scope: <0x111dc650>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %scevgep7 = getelementptr i8, i8* %lsr.iv, i64 3, !dbg !DILocation(line: 3, column: 31, scope: <0x111dd510>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  %exitcond.not = icmp eq i8 %inc, 32, !dbg !DILocation(line: 3, column: 31, scope: <0x111dd510>)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body, !dbg !DILocation(line: 3, column: 3, scope: <0x111dc650>), !llvm.loop <0x111de7b0><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">; Exit blocks<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">for.cond.cleanup:                                 ; preds = %for.body<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">  ret void, !dbg !DILocation(line: 7, column: 1, scope: <0x111d4030>)<o:p></o:p></span></p>
<p class="MsoNormal">---<o:p></o:p></p>
</div>
</body>
</html>