<div dir="ltr">Why does gcc xor down to a byte? Can't you get the parity flag for the whole value by just oring with itself and grabbing the flag?<div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Jul 20, 2018 at 11:37 AM Bruce Hoult via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This looks (not closely checked) like it's implementing the first part of pop1() combined with the last part of pop3(). Which is suggested in the comment just after pop1().<div><br></div><div><a href="http://www.hackersdelight.org/hdcodetxt/pop.c.txt" target="_blank">http://www.hackersdelight.org/hdcodetxt/pop.c.txt</a><br></div><div><br></div><div>And then anding with 1, obviously.</div><div><br></div><div>I wonder if division is good enough on modern machines to make pop2() faster.</div><div><br></div><div>XORing down to a byte and then using the x86 built in parity flag is obviously better if you are on an x86, of course. Other machines don't usually have that.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 20, 2018 at 11:02 AM, via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="#0563C1" vlink="#954F72"><div class="m_-9053016242030405932m_-5226560529932248255WordSection1"><p class="MsoNormal">Hello all!<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">I’ve been mucking around in an old codebase at work looking for easy performance wins. One avenue involves replacing a switch-based variable assignment with something derived from the parity of an input variable. I was pretty surprised when I saw the generated assembly, and I’m wondering about the reasoning behind it.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">In short, it boils down to the assembly <span style="font-family:Consolas">__builtin_parity()</span> produces. Clang 6.0.1 (and trunk on Godbolt) produces:<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><span style="font-family:Consolas">parity(int): # @parity(int)<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> mov eax, edi<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> shr eax<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> and eax, 1431655765<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> sub edi, eax<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> mov eax, edi<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> and eax, 858993459<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> shr edi, 2<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> and edi, 858993459<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> add edi, eax<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> mov eax, edi<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> shr eax, 4<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> add eax, edi<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> and eax, 17764111<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> imul eax, eax, 16843009<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> shr eax, 24<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> and eax, 1<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> ret<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"><u></u> <u></u></span></p><p class="MsoNormal">While GCC 8.1.0 (and trunk on Godbolt) produces<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><span style="font-family:Consolas">parity(int):<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> mov eax, edi<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> shr edi, 16<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> xor eax, edi<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> xor al, ah<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> setnp al<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> movzx eax, al<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"> ret<u></u><u></u></span></p><p class="MsoNormal"><span style="font-family:Consolas"><u></u> <u></u></span></p><p class="MsoNormal">I know a popcnt followed by an and would be better, but unfortunately some of my users don’t have computers that support the popcnt instruction, so I can’t use a newer -march flag.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Could someone explain why the difference between Clang and GCC here, and whether it should make a difference? The code in question is in a hot loop in my code, so I’d imagine the size difference could impact unrolling (and result in icache differences too), but I haven’t finished poking around with benchmarks.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Thanks,<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Alex <u></u><u></u></p></div></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>