<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:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 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;}
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.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}
@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">Philip, I appreciate your kind comments.<o:p></o:p></p>
<p><span style="font-size:10.0pt;font-family:"Courier New"">>In this example, forming the full pre/main/post loop structure of IRCE is overkill.  Instead, we could simply restrict the loop bounds in the following manner:<o:p></o:p></span></p>
<pre>><a href="http://loop.ph" target="_blank">loop.ph</a>:<o:p></o:p></pre>
<pre>>  ;; Warning: psuedo code, might have edge conditions wrong<o:p></o:p></pre>
<pre>>  %c = icmp sgt %iv, %n<o:p></o:p></pre>
<pre>>  %min = umax(%n, %a)<o:p></o:p></pre>
<pre>>  br i1 %c, label %exit, label %<a href="http://loop.ph" target="_blank">loop.ph</a><o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>loop.ph.split:<o:p></o:p></pre>
<pre>>  br label %loop<o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>loop:<o:p></o:p></pre>
<pre>>  %iv = phi i64 [ %inc, %loop ], [ 1, %<a href="http://loop.ph" target="_blank">loop.ph</a> ]<o:p></o:p></pre>
<pre>>  %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv <o:p></o:p></pre>
<pre>>  %val = load i64, i64* %src.arrayidx<o:p></o:p></pre>
<pre>>  %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv <o:p></o:p></pre>
<pre>>  store i64 %val, i64* %dst.arrayidx<o:p></o:p></pre>
<pre>>  %inc = add nuw nsw i64 %iv, 1<o:p></o:p></pre>
<pre>>  %cond = icmp eq i64 %inc, %min<o:p></o:p></pre>
<pre>>  br i1 %cond, label %exit, label %loop<o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>exit:<o:p></o:p></pre>
<pre>>  ret void<o:p></o:p></pre>
<pre>>}<o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>I'm not quite sure what to call this transform, but it's not IRCE.  If this example is actually general enough to cover your use cases, it's going to be a lot easier to judge profitability on than the general form of iteration set splitting<o:p></o:p></pre>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I agree with you. If the llvm community is ok to accept above approach as a pass or a part of a certain pass, I would be happy to implement it because I am aiming to handle this case with llvm upstream.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p><span style="font-size:10.0pt;font-family:"Courier New"">>Another way to frame this special case might be to recognize the conditional block can be inverted into an early exit.  (Reasoning: %iv is strictly increasing, condition is monotonic, path if not
 taken has no observable effect)  Consider:<o:p></o:p></span></p>
<pre>><a href="http://loop.ph" target="_blank">loop.ph</a>:<o:p></o:p></pre>
<pre>>  br label %loop<o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>loop:<o:p></o:p></pre>
<pre>>  %iv = phi i64 [ %inc, %for.inc ], [ 1, %<a href="http://loop.ph" target="_blank">loop.ph</a> ]<o:p></o:p></pre>
<pre>>  %cmp = icmp sge i64 %iv, %a<o:p></o:p></pre>
<pre>>  br i1 %cmp, label %exit, label %for.inc<o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>for.inc:<o:p></o:p></pre>
<pre>>  %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv <o:p></o:p></pre>
<pre>>  %val = load i64, i64* %src.arrayidx<o:p></o:p></pre>
<pre>>  %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv <o:p></o:p></pre>
<pre>>  store i64 %val, i64* %dst.arrayidx<o:p></o:p></pre>
<pre>>  %inc = add nuw nsw i64 %iv, 1<o:p></o:p></pre>
<pre>>  %cond = icmp eq i64 %inc, %n<o:p></o:p></pre>
<pre>>  br i1 %cond, label %exit, label %loop<o:p></o:p></pre>
<pre>><o:p> </o:p></pre>
<pre>>exit:<o:p></o:p></pre>
<pre>>  ret void<o:p></o:p></pre>
<pre>>}<o:p></o:p></pre>
<p><span style="font-size:10.0pt;font-family:"Courier New"">>Once that's done, the multiple exit vectorization work should vectorize this loop. Thinking about it, I really like this variant. 
<o:p></o:p></span></p>
<p class="MsoNormal"> I have not looked at the multiple exit vectorization work yet but it looks we could consider the inverted condition as early exit’s condition.<o:p></o:p></p>
<p><span style="font-size:10.0pt;font-family:"Courier New"">>The costing here seems quite off.  I have not looked at how the vectorize costs predicated loads on hardware without predication, but needing to scalarize a conditional VF-times and form a vector
 again does not have a cost of 3 million.  This could definitely be improved.<o:p></o:p></span></p>
<p class="MsoNormal">I agree with you.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Additionally, if possible, I would like to suggest to enable or add transformations in order to help vectorization. For example, as removing conditional branch inside loop, we could split a loop with dependency, which blocks vectorization,
 into vectorizable loop and non-vectorizable one using transformations like loop distribution. I am not sure why these features have not been enabled as default on pass manager but it would make more loops vectorizable.<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>
</body>
</html>