<div dir="ltr">It's fairly difficult to use CDQ in LLVM without tying the hands of the register allocator. It would potentially require a new post-RA combine pass to detect the "mov edx, eax; sar edx, 31" pattern. It's going to be even harder to bias register allocation in hopes of using CDQ for the lsign case.<div><br></div><div>CDQ is implemented in the shifter unit on a least the last several generations of Intel CPUs so its going to perform similarly to SAR. And the move only requires decoder bandwidth and no execution resources on recent CPUs. Do you performance data for this optimization?<br><div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Mar 3, 2019 at 11:08 PM Stefan Kanthak via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</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">Compile with -O3 -m32 (see <<a href="https://godbolt.org/z/yCpBpM" rel="noreferrer" target="_blank">https://godbolt.org/z/yCpBpM</a>>):<br>
<br>
long lsign(long x)<br>
{<br>
    return (x > 0) - (x < 0);<br>
}<br>
<br>
<br>
long long llsign(long long x)<br>
{<br>
    return (x > 0) - (x < 0);<br>
}<br>
<br>
<br>
While the code generated for the "long" version of this function is quite<br>
OK, the code for the "long long" version misses an obvious optimisation:<br>
<br>
<br>
lsign: # @lsign<br>
    mov     eax, dword ptr [esp + 4]    |    mov     eax, dword ptr [esp + 4]<br>
    xor     ecx, ecx                    |<br>
    test    eax, eax                    |    cdq<br>
    setg    cl                          |    neg     eax<br>
    sar     eax, 31                     |    adc     edx, edx<br>
    add     eax, ecx                    |    mov     eax, edx<br>
    ret                                 |    ret<br>
<br>
llsign: # @llsign<br>
    xor     ecx, ecx                    |    xor     edx, edx<br>
    mov     eax, dword ptr [esp + 8]    |    mov     eax, dword ptr [esp + 8]<br>
    cmp     ecx, dword ptr [esp + 4]    |    cmp     edx, dword ptr [esp + 4]<br>
    sbb     ecx, eax                    |    sbb     edx, eax<br>
    setl    cl                          |    cdq<br>
    sar     eax, 31                     |    setl    al<br>
    movzx   ecx, cl                     |    movzx   eax, al<br>
    add     eax, ecx                    |    add     eax, edx<br>
    mov     edx, eax                    |    ret<br>
    sar     edx, 31<br>
    ret<br>
<br>
NOTE: not just here this sequence SHOULD be replaced with<br>
<br>
    mov     edx, eax                    |    cdq<br>
    sar     edx, 31<br>
<br>
Although CDQ is the proper instruction for sign extension, LLVM/clang doesn't<br>
seem to like it.<br>
<br>
stay tuned<br>
Stefan Kanthak<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>