<div dir="ltr"><div>Hi Sjoerd,</div><div><br></div><div>thanks a lot for the clarification. Makes sense.</div><div><br></div><div>Kind regards,<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Missatge de Sjoerd Meijer <<a href="mailto:Sjoerd.Meijer@arm.com">Sjoerd.Meijer@arm.com</a>> del dia dt., 5 de maig 2020 a les 0:06:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">




<div dir="ltr">
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Hi Roger,</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
That's a good example, that shows most of the moving parts involved here. In a nutshell, the difference is, and what we would like to make explicit, is the vector trip versus the scalar loop trip count. In your IR example, the loads/stores are predicated on
 a mask that is calculated from a splat induction variable, which is compared with the vector trip count. Illustrated with your example simplified, and with some pseudo-code, if we tail-fold and vectorize this scalar loop:<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
for i= 0 to 10</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
  a[i] = b[i] + c[i];</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
the vector loop trip count is rounded up to 14, the next multiple of 4, and lanes are predicated on i < 10:<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
for i= 0 to 12</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
  a[i:4] = b[i:4] + c[i:4],    if i < 10;</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
what we would like to generate is a vector loop with implicit predication, which works by setting up the the number of elements processed by the loop:<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
hwloop 10<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
  [i:4] = b[i:4] + c[i:4]</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
This is implicit since instructions don't produce/consume a mask, but it is generated ans used under the hood by the "hwloop" construct. Your observation that the information in the IR is mostly there is correct, but rather than pattern matching and reconstructing
 this in the backend, we would like to makes this explicit. In this example, the scalar iteration count 10 iis the number of elements processed by this loop, which is what we want to pass on from the vectoriser to backend passes.</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
Hope this helps.</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
Cheers,</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
Sjoerd.<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt">
<br>
</div>
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div id="gmail-m_3172476292921851501appendonsend"></div>
<hr style="display:inline-block;width:98%">
<div id="gmail-m_3172476292921851501divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> Roger Ferrer Ibáñez <<a href="mailto:rofirrim@gmail.com" target="_blank">rofirrim@gmail.com</a>><br>
<b>Sent:</b> 04 May 2020 21:22<br>
<b>To:</b> Sjoerd Meijer <<a href="mailto:Sjoerd.Meijer@arm.com" target="_blank">Sjoerd.Meijer@arm.com</a>><br>
<b>Cc:</b> Eli Friedman <<a href="mailto:efriedma@quicinc.com" target="_blank">efriedma@quicinc.com</a>>; llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>>; Sam Parker <<a href="mailto:Sam.Parker@arm.com" target="_blank">Sam.Parker@arm.com</a>><br>
<b>Subject:</b> Re: [llvm-dev] LV: predication</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div>Hi Sjoerd,<br>
</div>
<br>
<div>
<blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
That would be an excellent way of doing it and it would also map very well to MVE too, where we have a VCTP intrinsic/instruction that creates the mask/predicate (Vector Create Tail-Predicate). So I will go for this approach. Such an intrinsic was actually
 also proposed in Sam's original RFC (see <a href="https://lists.llvm.org/pipermail/llvm-dev/2019-May/132512.html" id="gmail-m_3172476292921851501x_gmail-m_2362257955222971121LPlnk982545" target="_blank">
https://lists.llvm.org/pipermail/llvm-dev/2019-May/132512.html</a>), but we hadn't implemented it yet. This intrinsic will probably look something like this:</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
    <N x i1> @llvm.loop.get.active.mask(AnyInt, AnyInt)<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
It produces a <N x i1> predicate based on its two arguments, the number of elements and the vector trip count, and it will be used by the predicated masked loads/stores instructions in the vector body. I will start drafting an implementation for this and continue
 with this in D79100.<br>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>I'm curious about this, because this looks to me very similar to the code that -prefer-predicate-over-epilog is already emitting for the "outer mask" of a tail-folded loop.</div>
<div><br>
</div>
<div>The following code </div>
<div><br>
</div>
<div><span style="font-family:monospace">void foo(int N, int *restrict c, int *restrict a, int *restrict b) {<br>
#pragma clang loop vectorize(enable) interleave(disable)<br>
  for (int i = 0; i < N; i++) {<br>
    a[i] = b[i] + c[i];<br>
  }<br>
}</span></div>
<div><br>
</div>
<div>compiled with <span style="font-family:monospace">clang --target=x86_64 -mavx512f -mllvm -prefer-predicate-over-epilog -emit-llvm -O2</span> emits the following IR<br>
</div>
<div><span style="font-family:monospace"><br>
</span></div>
<div><span style="font-family:monospace">vector.body:                                      ; preds = %vector.body, %for.body.preheader.new<br>
  %index = phi i64 [ 0, %for.body.preheader.new ], [ %index.next.1, %vector.body ]<br>
  %niter = phi i64 [ %unroll_iter, %for.body.preheader.new ], [ %niter.nsub.1, %vector.body ]<br>
  %broadcast.splatinsert12 = insertelement <16 x i64> undef, i64 %index, i32 0<br>
  %broadcast.splat13 = shufflevector <16 x i64> %broadcast.splatinsert12, <16 x i64> undef, <16 x i32> zeroinitializer<br>
  %induction = or <16 x i64> %broadcast.splat13, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15><br>
  %4 = getelementptr inbounds i32, i32* %b, i64 %index<br>
  <b>%5 = icmp ule <16 x i64> %induction, %broadcast.splat</b><br>
  ...<br>
  %wide.masked.load = call <16 x i32> @llvm.masked.load.v16i32.p0v16i32(<16 x i32>* %6, i32 4,
<b><16 x i1> %5</b>, <16 x i32> undef), !tbaa !2</span><br>
</div>
<div><br>
</div>
<div>I understand <span style="font-family:monospace">%5</span> is not the same your proposed llvm.loop.get.active.mask would compute, is that correct? Can you elaborate on the difference here?</div>
<div><br>
</div>
<div>Thanks a lot,<br>
</div>
<div>Roger<br>
</div>
</div>
</div>
</div>
</div>

</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature">Roger Ferrer Ibáñez<br></div>