<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 21, 2020 at 1:44 PM Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<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 dir="ltr"><div dir="ltr">On Mon, Sep 21, 2020 at 7:02 AM Bart Samwel via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><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">Hi there folks,<div><br></div><div>I wonder if anybody can shed some light on this. I'm looking at a function with a parameter pack argument and one without, that should do the exact same thing.</div><div><br></div><div><a href="https://godbolt.org/z/Keqzcj" target="_blank">https://godbolt.org/z/Keqzcj</a> <br clear="all"><div><br></div><div>However, the version with the parameter pack expands (at -O3 -march=broadwell, on clang 10.0.1, on godbolt) into a loop per 128 bytes, plus a loop per 64 bytes, plus nonvectorized instructions to process the remaining <=63 bytes. The manual version expands to just a loop per 128 bytes (256-bit vectors, unrolled 4x), and nonvectorized instructions to process the remaining <=127 bytes.</div></div></div></blockquote><div><br></div><div>It's about the fold expression.</div><div><a href="https://godbolt.org/z/EPETj9" target="_blank">https://godbolt.org/z/EPETj9</a><br></div><div><br></div><div>With C++17 fold-expressions, (args | ...) doesn't mean (arg1 | arg2 | arg3); it means (arg1 | (arg2 | arg3)).  So with the right-fold you wrote, you're telling the compiler to OR the values together "right-to-left", whereas the non-template version does it "left-to-right": ((arg1 | arg2) | arg3). And apparently this makes some huge difference to the codegen (which is still mysterious to me, but out of my depth).</div></div></div></div></blockquote><div> </div><div>That is just plain weird, and probably interesting for the codegen folks to look at. :) Thanks a lot for figuring this out! </div><div> </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 dir="ltr"><div class="gmail_quote"><div><br></div><div>Switch the right-fold to a left-fold and the codegen becomes identical, at least to my eyes. (In the above Godbolt, put -DVARIADIC in one compiler frame and nothing in the other.)</div><div><br></div><div>–Arthur</div></div></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div style="font-size:12.8px"><div style="color:rgb(136,136,136);font-size:12.8px"><span style="font-size:12.8px;color:rgb(34,34,34)">Bart Samwel</span><br></div><div style="font-size:12.8px"><a href="mailto:bart.samwel@databricks.com" target="_blank">bart.samwel@databricks.com</a></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><img src="https://docs.google.com/uc?export=download&id=1iplOU5OHdtakkH1xKbxfcB-4BA6DXfKc&revid=0B9RlGdocqKy4L2hpckhpbmM4dmNIekJpVVhNamlndmFzYUprPQ" width="200" height="32"><br></div><div style="font-size:12.8px"><p dir="ltr" style="font-size:12.8px;line-height:1.2;margin-top:0pt;margin-bottom:0pt"></p></div></div></div></div></div></div></div></div></div></div></div></div></div></div>