<div dir="ltr"><div class="gmail_quote">On Wed, Apr 15, 2015 at 5:17 AM James Molloy <<a href="mailto:james@jamesmolloy.co.uk">james@jamesmolloy.co.uk</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<br><br>There seem several ways to implement this. The ones I've seen mooted so far are:<div>  * Pattern-matching "SAD-style" in the vectorizer - see Intel's SAD patch for details.</div><div>  * Demanded-bits analysis allowing type demotion (my idea).</div><div>  * What Chandler just suggested.</div><div><br></div><div>Does anyone have views on which is best? I agree that this is a problem that really needs a solution.</div></div></blockquote><div><br></div><div>We need all three IMO.</div><div><br></div><div>When we have really precise patterns, we need to do that: SAD, CRC, etc.</div><div><br></div><div>We should also do demanded-bits analysis to try to do type demotion.</div><div><br></div><div>We should also do other strategies to narrow types.</div><div><br></div><div>While clearly we should prioritize these based on specific problems that need solving, I think long term we're really going to need to cover all of our bases here. Getting the maximum bandwidth out of the vector unit when we've found code that can run inside the unit is too important to miss anything significant IMO.</div><div><br></div><div>-Chandler</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Cheers,</div><div><br></div><div>James</div></div><br><div class="gmail_quote">On Wed, 15 Apr 2015 at 11:08 Chandler Carruth <<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote">On Tue, Apr 14, 2015 at 11:25 AM Cong Hou <<a href="mailto:congh@google.com" target="_blank">congh@google.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Apr 14, 2015 at 8:49 AM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote">I've replied to some of the higher level concerns already, but I wanted to point out one specific thing:</div><span><div class="gmail_quote"><br></div><div class="gmail_quote">On Fri, Apr 10, 2015 at 3:30 AM Cong Hou <<a href="mailto:congh@google.com" target="_blank">congh@google.com</a>> wrote:<br></div></span><div class="gmail_quote"><span><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">LLVM uses the widest type to calculate the maximum vectorization factor, which greatly limits the bandwidth of either calculations or loads/stores from SIMD instructions. One example is converting 8-bit integers to 32-bit integers from arrays in a loop: currently the VF of this simple loop is decided by 32-bit integer and for SSE2 it will be 4. Then we will have 1 load and 1 store in every 4 iterations. If we calculate VF based on 8-bit integer, which will be 16, we will have 1 load and 4 stores in every 16 iterations, saving many loads.<br></blockquote><div><br></div></span><div>While I'm generally in favor of this kind of change, I think the test case you're looking at is actually a separate issue that I've written up several times w.r.t. our vectorizer.</div></div></div></blockquote><div><br></div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>You mean fp64_to_uint32-cost-model.ll? I think you are right. My patch invalidates this test and that is why I need to change the test criteria.</div></div></div></div></blockquote><div><br></div></div></div><div dir="ltr"><div class="gmail_quote"><div>No, I meant the benchmarks you're looking at. But I'm guessing which benchmarks, so completely possible I've guessed incorrectly! =D Anyways, it seems were on the same page here...</div></div></div><div dir="ltr"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div><br></div><div>Because C does integer promotion from 8-bit integer types to 32-bit integer types, we very commonly see things that are vectorized with 32-bit integer math when they don't need to.</div></div></div></blockquote><div><br></div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Yes, the promotion to 32-bit integers are quite annoying to vectorizer: too many packing/unpacking instructions will be generated which could be eliminated if directly doing operations on 8-bit integers won't affect the results.</div></div></div></div></blockquote><div><br></div></div></div><div dir="ltr"><div class="gmail_quote"><div>It also causes bandwidth limitation (or register pressure hit). I just wonder if fixing this issue would also fix the bandwidth issues you've seen.</div></div></div><div dir="ltr"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div><br></div><div>The IR can't narrow these operations from 32-bit integer operations to 8-bit integer operations without losing information because in 8-bits the operations might overflow. But when vectorizing, we don't care about this. We should aggressively narrow operations above a trunc which we could hoist the trunc above by stripping overflow flags while building the vectorizable operation tree so that we can fit more operations into a single vector. Does that make sense?</div></div></div></blockquote><div><br></div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>That is also what I am thinking about. If LLVM supports pattern recognition (like in GCC), we could recognize this type-promotion-then-demotion as a pattern then generate better vectorized code. The pattern recognizer can also help generate better SIMD code for dot-product/SAD/widening operations. I am not sure how the SAD patch is implemented and hope we could have a general way to detect those patterns.</div></div></div></div></blockquote><div><br></div></div></div><div dir="ltr"><div class="gmail_quote"><div>I'm not suer what you mean by supporting pattern recognition. We do a great deal of pattern matching on the IR?</div><div><br></div><div>I don't know that you need to specifically match type-promotion-then-demotion. I think that's unnecessarily narrow. If the vectorizer sees code:</div><div><br></div><div>...</div><div>%x = add nsw i32 %a, %a</div><div>%y = trunc i32 %x to i8</div><div>store i8 %y, i8* %ptr</div><div><br></div><div>And it would form:</div><div><br></div><div>...</div><div>%x.v = add nsw <4 x i32> %a.v, %a.v</div><div>%y.v = trunc <4 x i32> %x.v to <4 x i8></div><div>store <4 x i8> %y.v, <4 x i8>* %ptr.v</div><div><br></div><div>It seems likely beneficial to instead teach the vectorizer to hoist the trunc over the "add nsw", removing the "nsw" to preserve semantics. Sure, you wouldn't want to do this if it would increase the number of trunc instructions, or if the operations aren't supported on the target (or have very high cost). But if it doesn't increase the number of instructions (either because we having a single input, or because it allows the vectorizer to use a wider vector) it seems generally good. Maybe the case where there is a matching zext is the only easy case to prove, but it seems worth looking at from a general perspective.</div></div></div><div dir="ltr"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>Cong</div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><span><font color="#888888"><div><br></div><div>-Chandler</div><div> </div></font></span><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>
<br>
This patch mainly changes the function getWidestType() to getNarrowestType(), and uses it to calculate VF.<br>
<br>
<a href="http://reviews.llvm.org/D8943" target="_blank">http://reviews.llvm.org/D8943</a><br>
<br>
Files:<br>
  lib/Target/X86/X86TargetTransformInfo.cpp<br>
  lib/Transforms/Vectorize/LoopVectorize.cpp<br>
  test/Transforms/LoopVectorize/X86/fp64_to_uint32-cost-model.ll<br>
  test/Transforms/LoopVectorize/X86/vector_ptr_load_store.ll<br>
<br>
EMAIL PREFERENCES<br>
  <a href="http://reviews.llvm.org/settings/panel/emailpreferences/" target="_blank">http://reviews.llvm.org/settings/panel/emailpreferences/</a><br></span><span>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</span></blockquote></div></div>
</blockquote></div></div></div></blockquote></div></div>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</blockquote></div></div>