<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=utf-8">
<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;}
@font-face
        {font-family:"Malgun Gothic";
        panose-1:2 11 5 3 2 0 0 2 0 4;}
@font-face
        {font-family:"\@Malgun Gothic";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        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;}
--></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-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Ping<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b>From:</b> llvm-dev <llvm-dev-bounces@lists.llvm.org> <b>On Behalf Of
</b>Jingu Kang via llvm-dev<br>
<b>Sent:</b> 27 October 2021 15:15<br>
<b>To:</b> llvm-dev@lists.llvm.org<br>
<b>Subject:</b> [llvm-dev] Question about hoisting LoadInst in LICM pass using MemorySSA/AliasAnalysis<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi All,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I have a question about hoisting LoadInst in LICM pass. I am looking at below IR code.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">@a = dso_local local_unnamed_addr global i32** null, align 8<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">define dso_local void @foo(i32 %max) {<o:p></o:p></p>
<p class="MsoNormal">entry:<o:p></o:p></p>
<p class="MsoNormal">  br label %for.cond<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">for.cond:                                         ; preds = %for.body, %entry<o:p></o:p></p>
<p class="MsoNormal">  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]<o:p></o:p></p>
<p class="MsoNormal">  %cmp.not = icmp sgt i32 %i.0, %max<o:p></o:p></p>
<p class="MsoNormal">  br i1 %cmp.not, label %for.cond.cleanup, label %for.body<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">for.cond.cleanup:                                 ; preds = %for.cond<o:p></o:p></p>
<p class="MsoNormal">  ret void<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">for.body:                                         ; preds = %for.cond<o:p></o:p></p>
<p class="MsoNormal">  %0 = load i32**, i32*** @a, align 8, !tbaa !8<o:p></o:p></p>
<p class="MsoNormal">  %idxprom = zext i32 %i.0 to i64<o:p></o:p></p>
<p class="MsoNormal">  %arrayidx = getelementptr inbounds i32*, i32** %0, i64 %idxprom<o:p></o:p></p>
<p class="MsoNormal">  store i32* null, i32** %arrayidx, align 8, !tbaa !8<o:p></o:p></p>
<p class="MsoNormal">  %inc = add nuw nsw i32 %i.0, 1<o:p></o:p></p>
<p class="MsoNormal">  br label %for.cond, !llvm.loop !12<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I have expected the `%0 = load` is hoisted to entry block because I think it is loop invariant. However, LICM pass fails to hoist it because the MemorySSA is as below.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">define dso_local void @foo(i32 %max) local_unnamed_addr #0 {<o:p></o:p></p>
<p class="MsoNormal">entry:<o:p></o:p></p>
<p class="MsoNormal">  br label %for.cond<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">for.cond:                                         ; preds = %for.body, %entry<o:p></o:p></p>
<p class="MsoNormal">; 2 = MemoryPhi({entry,liveOnEntry},{for.body,1})<o:p></o:p></p>
<p class="MsoNormal">  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]<o:p></o:p></p>
<p class="MsoNormal">  %cmp.not = icmp sgt i32 %i.0, %max<o:p></o:p></p>
<p class="MsoNormal">  br i1 %cmp.not, label %for.cond.cleanup, label %for.body<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">for.cond.cleanup:                                 ; preds = %for.cond<o:p></o:p></p>
<p class="MsoNormal">  ret void<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">for.body:                                         ; preds = %for.cond<o:p></o:p></p>
<p class="MsoNormal">; MemoryUse(2) MayAlias<o:p></o:p></p>
<p class="MsoNormal">  %0 = load i32**, i32*** @a, align 8, !tbaa !8<o:p></o:p></p>
<p class="MsoNormal">  %idxprom = zext i32 %i.0 to i64<o:p></o:p></p>
<p class="MsoNormal">  %arrayidx = getelementptr inbounds i32*, i32** %0, i64 %idxprom<o:p></o:p></p>
<p class="MsoNormal">; 1 = MemoryDef(2)<o:p></o:p></p>
<p class="MsoNormal">  store i32* null, i32** %arrayidx, align 8, !tbaa !8<o:p></o:p></p>
<p class="MsoNormal">  %inc = add nuw nsw i32 %i.0, 1<o:p></o:p></p>
<p class="MsoNormal">  br label %for.cond, !llvm.loop !12<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As we can see there is `MemoryUse(2) MayAlias` above the `%0 = load` because AliasAnalysis returns MayAlias between the ‘%0 = load’ and ‘store i32* null’. I think it could be `MemoryUse(liveOnEntry)`. How do you think about it? If I missed
 something, please let me know.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal">JinGu Kang<o:p></o:p></p>
</div>
</div>
</body>
</html>