<div dir="auto">I was mostly speaking to abssi2. What data dependency exists for cmov that doesn’t exist for cdq+add+xor?</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Sep 6, 2020 at 1:19 PM Stefan Kanthak <<a href="mailto:stefan.kanthak@nexgo.de">stefan.kanthak@nexgo.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">"Craig Topper" <<a href="mailto:craig.topper@gmail.com" target="_blank">craig.topper@gmail.com</a>> wrote:<br><br><br><br>> Sorry. I made a mistake. Cmov has been 1 cycle since Broadwell.<br><br><br><br>Doesn't matter, no need to worry: all instructions used below run in 1 cycle on<br><br>recent CPUs ... just like Jcc. The question/point is but whether the CPU can/does<br><br>speculate ahead.<br><br><br><br>Stefan<br><br><br><br>On Sun, Sep 6, 2020 at 12:39 PM Craig Topper <<a href="mailto:craig.topper@gmail.com" target="_blank">craig.topper@gmail.com</a>> wrote:<br><br><br><br>> cmov has been 1 cycle since Sandy Bridge. Moves execute in the register<br><br>> renamer since Ivy Bridge. So mov+neg+cmov should be faster than cdq+add+xor<br><br>> on modern CPUs. Furthermore, cdq really ties the hands of the register<br><br>> allocator so probably doesn't make sense in a larger function with abs<br><br>> mixed with other code.<br><br>><br><br>> ~Craig<br><br>><br><br>><br><br>> On Sun, Sep 6, 2020 at 12:30 PM Stefan Kanthak via cfe-dev <<br><br>> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br><br>><br><br>>> --- bugs-bunny.c ---<br><br>>> // Copyleft © 2014-2020, Stefan Kanthak <<a href="mailto:stefan.kanthak@nexgo.de" target="_blank">stefan.kanthak@nexgo.de</a>><br><br>>><br><br>>> #ifdef __amd64__<br><br>>> __int128_t __absti2(__int128_t argument) {<br><br>>>     return argument < 0 ? -argument : argument;<br><br>>> }<br><br>>> #else<br><br>>> long long __absdi2(long long argument) {<br><br>>> #ifdef BUNNY<br><br>>>     return __builtin_llabs(argument);<br><br>>> #else<br><br>>>     return argument < 0 ? -argument : argument;<br><br>>> #endif // BUNNY<br><br>>> }<br><br>>><br><br>>> long __abssi2(long argument) {<br><br>>> #ifdef BUNNY<br><br>>>     return __builtin_labs(argument);<br><br>>> #else<br><br>>>     return argument < 0 ? -argument : argument;<br><br>>> #endif // BUNNY<br><br>>> }<br><br>>> #endif // __amd64__<br><br>>> --- EOF ---<br><br>>><br><br>>> Run clang -c -o- -O3 -S -target amd64-pc-linux bugs-bunny.c<br><br>>><br><br>>> Left: inperformant original code # right: proper code,<br><br>>>                                  #        faster and 3 bytes shorter<br><br>>><br><br>>> __absti2:      # @__absti2<br><br>>> # %bb.0:                         # .intel_syntax noprefix<br><br>>>       xorl     %edx, %edx        #        mov    rax, rsi<br><br>>>       movq     %rdi, %rax        #        cqo<br><br>>>       negq     %rax              #        mov    rax, rdx<br><br>>>       sbbq     %rsi, %rdx        #        add    rdi, rdx<br><br>>>       testq    %rsi, %rsi        #        adc    rsi, rdx<br><br>>>       cmovnsq  %rdi, %rax        #        xor    rax, rdi<br><br>>>       cmovnsq  %rsi, %rdx        #        xor    rdx, rsi<br><br>>>       retq                       #        ret<br><br>>><br><br>>> CMOVcc introduces a data dependency here, WITHOUT necessity!<br><br>>><br><br>>><br><br>>> Run clang -c -o- -O3 -S -target i386-pc-linux bugs-bunny.c<br><br>>><br><br>>> Left: inperformant original code # right: proper code, runs even on real<br><br>>>                                  #        i386, not just PentiumPro+<br><br>>><br><br>>> ___abssi2:    # @__abssi2<br><br>>> # %bb.0:                         # .intel_syntax noprefix<br><br>>>       movl    4(%esp), %ecx      #        mov    eax, [esp+4]<br><br>>>       movl    %ecx, %eax         #        cdq<br><br>>>       negl    %eax               #        add    eax, edx<br><br>>>       cmovll  %ecx, %eax         #        xor    eax, edx<br><br>>>       retl                       #        ret<br><br>>><br><br>>><br><br>>> Writing shorter code for __absdi2() for i386 is left as an<br><br>>> exercise to the reader.<br><br>>><br><br>>> _______________________________________________<br><br>>> cfe-dev mailing list<br><br>>> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br><br>>> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br><br>>><br><br><br><br></blockquote></div></div>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div>