<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=iso-8859-1">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Batang;
panose-1:2 3 6 0 0 1 1 1 1 1;}
@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:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
{font-family:"\@Malgun Gothic";}
@font-face
{font-family:"\@Batang";
panose-1:2 3 6 0 0 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0cm;
font-size:10.0pt;
font-family:"Courier New";}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:Consolas;}
span.EmailStyle21
{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="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Sorry for poor example…<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The AArch64 assembly output of the example from gcc is as below. The loop is unrolled 7 times. I have written some comments to explain how the assembly code is mapped to C source code. As you can see on `.L3` label, the ‘if (*s++ != '\n')’
block is unrolled 7 times. <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> stp x29, x30, [sp, -48]!<o:p></o:p></p>
<p class="MsoNormal"> mov x29, sp<o:p></o:p></p>
<p class="MsoNormal"> stp x19, x20, [sp, 16]<o:p></o:p></p>
<p class="MsoNormal"> mov x19, x0 --> x19 is char *s<o:p></o:p></p>
<p class="MsoNormal"> mov x20, x1 --> x20 is char *end<o:p></o:p></p>
<p class="MsoNormal"> str x21, [sp, 32]<o:p></o:p></p>
<p class="MsoNormal"> orr x21, x3, x2 --> x21 is check1 | check2<o:p></o:p></p>
<p class="MsoNormal">.L70:<o:p></o:p></p>
<p class="MsoNormal"> sub x0, x20, x19 --> x0 = end - s;<o:p></o:p></p>
<p class="MsoNormal"> add x1, x0, 1<o:p></o:p></p>
<p class="MsoNormal"> ands x2, x1, 7 --> unroll count is 7<o:p></o:p></p>
<p class="MsoNormal"> beq .L3 --> .L3 is inside while loop. if (*s++ != '\n')<o:p></o:p></p>
<p class="MsoNormal"> cmp x19, x20 --> while(s <= end)<o:p></o:p></p>
<p class="MsoNormal"> bhi .L2 --> .L2 is label ret1.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> ldrb w3, [x19], 1 --> start of remainder<o:p></o:p></p>
<p class="MsoNormal"> cmp w3, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> cmp x2, 1<o:p></o:p></p>
<p class="MsoNormal"> beq .L3<o:p></o:p></p>
<p class="MsoNormal"> cmp x2, 2<o:p></o:p></p>
<p class="MsoNormal"> beq .L49<o:p></o:p></p>
<p class="MsoNormal"> cmp x2, 3<o:p></o:p></p>
<p class="MsoNormal"> beq .L50<o:p></o:p></p>
<p class="MsoNormal"> cmp x2, 4<o:p></o:p></p>
<p class="MsoNormal"> beq .L51<o:p></o:p></p>
<p class="MsoNormal"> cmp x2, 5<o:p></o:p></p>
<p class="MsoNormal"> beq .L52<o:p></o:p></p>
<p class="MsoNormal"> cmp x2, 6<o:p></o:p></p>
<p class="MsoNormal"> beq .L53<o:p></o:p></p>
<p class="MsoNormal"> ldrb w4, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w4, 10<o:p></o:p></p>
<p class="MsoNormal"> bne .L53<o:p></o:p></p>
<p class="MsoNormal">.L71:<o:p></o:p></p>
<p class="MsoNormal"> cbz x21, .L4 --> if(check1 || check2)<o:p></o:p></p>
<p class="MsoNormal"> bl foo()<o:p></o:p></p>
<p class="MsoNormal"> mov x19, x0<o:p></o:p></p>
<p class="MsoNormal"> cbz x0, .L2 --> if (!s) goto ret1;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">.L4: --> if(boo(s)) goto ret0;<o:p></o:p></p>
<p class="MsoNormal"> mov x0, x19<o:p></o:p></p>
<p class="MsoNormal"> bl boo(char*)<o:p></o:p></p>
<p class="MsoNormal"> cbz w0, .L70<o:p></o:p></p>
<p class="MsoNormal"> mov w0, 0<o:p></o:p></p>
<p class="MsoNormal"> ldp x19, x20, [sp, 16]<o:p></o:p></p>
<p class="MsoNormal"> ldr x21, [sp, 32]<o:p></o:p></p>
<p class="MsoNormal"> ldp x29, x30, [sp], 48<o:p></o:p></p>
<p class="MsoNormal"> ret<o:p></o:p></p>
<p class="MsoNormal">.L53: --> if (*s++ != '\n') for remainder<o:p></o:p></p>
<p class="MsoNormal"> ldrb w5, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w5, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal">.L52: --> if (*s++ != '\n') for remainder<o:p></o:p></p>
<p class="MsoNormal"> ldrb w6, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w6, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal">.L51: --> if (*s++ != '\n') for remainder<o:p></o:p></p>
<p class="MsoNormal"> ldrb w7, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w7, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal">.L50: --> if (*s++ != '\n') for remainder<o:p></o:p></p>
<p class="MsoNormal"> ldrb w8, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w8, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal">.L49: --> if (*s++ != '\n') for remainder<o:p></o:p></p>
<p class="MsoNormal"> ldrb w9, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w9, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal">.L3: --> if (*s++ != '\n'), 7 times unrolled<o:p></o:p></p>
<p class="MsoNormal"> cmp x19, x20<o:p></o:p></p>
<p class="MsoNormal"> bhi .L2<o:p></o:p></p>
<p class="MsoNormal"> ldrb w10, [x19]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x19, 1<o:p></o:p></p>
<p class="MsoNormal"> mov x11, x19<o:p></o:p></p>
<p class="MsoNormal"> cmp w10, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w12, [x19], 1<o:p></o:p></p>
<p class="MsoNormal"> cmp w12, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w13, [x11, 1]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x11, 2<o:p></o:p></p>
<p class="MsoNormal"> cmp w13, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w14, [x11, 2]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x11, 3<o:p></o:p></p>
<p class="MsoNormal"> cmp w14, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w15, [x11, 3]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x11, 4<o:p></o:p></p>
<p class="MsoNormal"> cmp w15, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w16, [x11, 4]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x11, 5<o:p></o:p></p>
<p class="MsoNormal"> cmp w16, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w17, [x11, 5]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x11, 6<o:p></o:p></p>
<p class="MsoNormal"> cmp w17, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> ldrb w18, [x11, 6]<o:p></o:p></p>
<p class="MsoNormal"> add x19, x11, 7<o:p></o:p></p>
<p class="MsoNormal"> cmp w18, 10<o:p></o:p></p>
<p class="MsoNormal"> beq .L71<o:p></o:p></p>
<p class="MsoNormal"> b .L3<o:p></o:p></p>
<p class="MsoNormal">.L2: --> label ret1<o:p></o:p></p>
<p class="MsoNormal"> mov w0, 1<o:p></o:p></p>
<p class="MsoNormal"> ldp x19, x20, [sp, 16]<o:p></o:p></p>
<p class="MsoNormal"> ldr x21, [sp, 32]<o:p></o:p></p>
<p class="MsoNormal"> ldp x29, x30, [sp], 48<o:p></o:p></p>
<p class="MsoNormal"> ret<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I am sorry for showing you assembly output directly… It looks like the rtl level’s unroll pass of gcc unrolls above loop and I need to check it next week. Once I have clear idea about above unrolling from gcc, let me reduce the example
more and let you 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>
<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>Philip Reames via llvm-dev<br>
<b>Sent:</b> 16 July 2021 18:27<br>
<b>To:</b> Jingu Kang <Jingu.Kang@arm.com><br>
<b>Cc:</b> llvm-dev@lists.llvm.org<br>
<b>Subject:</b> Re: [llvm-dev] Question about Unrolling Loop with Multiple Exits<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p><o:p> </o:p></p>
<div>
<p class="MsoNormal">On 7/16/21 9:29 AM, Jingu Kang wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p>Hi Philip,<o:p></o:p></p>
<p>Thanks for your kind reply.<o:p></o:p></p>
<p>> A) Are you measuring on tip of tree?� There were changes for multiple exit unrolling which landed very recently.<o:p></o:p></p>
<p>Yep, I am investigating benchmarks with llvm tip and I can see the llvm fails to unroll some loops with multiple exits.<o:p></o:p></p>
<p class="MsoNormal">> B) One of your exits does not dominate your latch.� Those are generally hard<o:p></o:p></p>
<p class="MsoNormal">> C) This example does not seem to require gotos.� I strongly suggest reducing your test cases if you want more informed commentary.�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">I am looking at perlbench recently and it has `goto` statements inside loop. The example is a reduced case.
<o:p></o:p></p>
</blockquote>
<p class="MsoNormal">Right, but the gotos aren't relevant for your reduced test.� You can reduce further.<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">When I look at the gcc�s output of the example, it looks like gcc unrolls only the below `if` statement block�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">��� if (*s++ != '\n')<o:p></o:p></p>
<p class="MsoNormal">����� continue;<o:p></o:p></p>
</blockquote>
<p class="MsoNormal">Your phrasing here does not parse for me.� Can you restate this with different wording and maybe a fully worked example?<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<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>
<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 <a href="mailto:llvm-dev-bounces@lists.llvm.org">
<llvm-dev-bounces@lists.llvm.org></a> <b>On Behalf Of </b>Philip Reames via llvm-dev<br>
<b>Sent:</b> 16 July 2021 15:52<br>
<b>To:</b> Jingu Kang <a href="mailto:Jingu.Kang@arm.com"><Jingu.Kang@arm.com></a>;
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<b>Subject:</b> Re: [llvm-dev] Question about Unrolling Loop with Multiple Exits<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal">�<o:p></o:p></p>
<p>A) Are you measuring on tip of tree?� There were changes for multiple exit unrolling which landed very recently.<o:p></o:p></p>
<p>B) One of your exits does not dominate your latch.� Those are generally hard.�
<o:p></o:p></p>
<p>C) This example does not seem to require gotos.� I strongly suggest reducing your test cases if you want more informed commentary.�
<o:p></o:p></p>
<p>Philip<o:p></o:p></p>
<div>
<p class="MsoNormal">On 7/16/21 7:42 AM, Jingu Kang via llvm-dev wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">Hi All,<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">While I am investigating benchmarks, I have found loops which llvm fails to unroll because the loops have multiple exits.<o:p></o:p></p>
<p class="MsoNormal">For example, <o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">char *foo(void);<o:p></o:p></p>
<p class="MsoNormal">int boo(char *s);<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">int test(char *s, char *end, char *check1, char *check2) {<o:p></o:p></p>
<p class="MsoNormal">� while (s <= end) {<o:p></o:p></p>
<p class="MsoNormal">��� if (*s++ != '\n')<o:p></o:p></p>
<p class="MsoNormal">����� continue;<o:p></o:p></p>
<p class="MsoNormal">��� if (check1 || check2) {<o:p></o:p></p>
<p class="MsoNormal">����� s = foo();<o:p></o:p></p>
<p class="MsoNormal">����� if (!s)<o:p></o:p></p>
<p class="MsoNormal">������� goto ret1;<o:p></o:p></p>
<p class="MsoNormal">��� }�� <o:p></o:p></p>
<p class="MsoNormal">����if (boo(s))<o:p></o:p></p>
<p class="MsoNormal">����� goto ret0;<o:p></o:p></p>
<p class="MsoNormal">� }<o:p></o:p></p>
<p class="MsoNormal">� goto ret1;<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">ret0:<o:p></o:p></p>
<p class="MsoNormal">� return 0;<o:p></o:p></p>
<p class="MsoNormal">ret1:<o:p></o:p></p>
<p class="MsoNormal">� return 1;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">Above code causes below messages from LoopUnroll pass.<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">Bailout for multi-exit handling when latch exit has >1 predecessor.<o:p></o:p></p>
<p class="MsoNormal">Multiple exit/exiting blocks in loop and multi-exit unrolling not enabled!<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">I can see the option `unroll-runtime-multi-exit` and comments about it. I wonder there are already reviews for the work on phabriactor or some people are working on it.<o:p></o:p></p>
<p class="MsoNormal">If someone knows information about it, please share it.<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>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal">�<o:p></o:p></p>
<p class="MsoNormal"><br>
<br>
<br>
<o:p></o:p></p>
<pre>_______________________________________________<o:p></o:p></pre>
<pre>LLVM Developers mailing list<o:p></o:p></pre>
<pre><a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><o:p></o:p></pre>
<pre><a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><o:p></o:p></pre>
</blockquote>
</div>
</blockquote>
</div>
</div>
</body>
</html>