<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Apr 15, 2015 at 3:04 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><span class="">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></span><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></blockquote><div><br></div><div>OK. Now I know what you mean...</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 class="gmail_quote"><span class=""><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></span><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></blockquote><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"><span class=""><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></span><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></blockquote><div><br></div><div>If we hoist "trunc" over "add nsw" we need more trunc operations as there are two operands in "add nsw". This may not always be beneficial. However, if those operands are obtained from "type promotion from i8 to i32" then we don't need those trunc operations anymore because we already have both operands of type <4 x i8> ready. This is can be done by type-promotion-then-demotion pattern recognition I have mentioned. One advantage of this method is that it is easier to calculate the more precise cost in our cost model.<br></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 class="gmail_quote"><span class=""><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></span></div></div>
</blockquote></div><br></div></div>