Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>EDIT: Saw OP's assembly listing for my code. I doubt this is even a <em>general bug with VS2011</em> now. This may simply be a special case bug for OP's code. I ran OP's code as-is with clang 3.2, gcc 4.6.2 and VS2010 and in all cases the <em>max differences</em> were at ~1%.</p> </blockquote> <p>Just compiled the sources with suitable modifications to my <code>ne.c</code> file and the <code>/O2</code> and <code>/GL</code> flags. Here's the source </p> <pre><code>int ne1(int n) { return n != 0; } int ne2(int n) { return n &lt; 0 || n &gt; 0; } int ne3(int n) { return !(n == 0); } int main() { int p = ne1(rand()), q = ne2(rand()), r = ne3(rand());} </code></pre> <p>and the corresponding assembly:</p> <pre><code> ; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLE D:\llvm_workspace\tests\ne.c .686P .XMM include listing.inc .model flat INCLUDELIB OLDNAMES EXTRN @__security_check_cookie@4:PROC EXTRN _rand:PROC PUBLIC _ne3 ; Function compile flags: /Ogtpy ; COMDAT _ne3 _TEXT SEGMENT _n$ = 8 ; size = 4 _ne3 PROC ; COMDAT ; File d:\llvm_workspace\tests\ne.c ; Line 11 xor eax, eax cmp DWORD PTR _n$[esp-4], eax setne al ; Line 12 ret 0 _ne3 ENDP _TEXT ENDS PUBLIC _ne2 ; Function compile flags: /Ogtpy ; COMDAT _ne2 _TEXT SEGMENT _n$ = 8 ; size = 4 _ne2 PROC ; COMDAT ; Line 7 xor eax, eax cmp eax, DWORD PTR _n$[esp-4] sbb eax, eax neg eax ; Line 8 ret 0 _ne2 ENDP _TEXT ENDS PUBLIC _ne1 ; Function compile flags: /Ogtpy ; COMDAT _ne1 _TEXT SEGMENT _n$ = 8 ; size = 4 _ne1 PROC ; COMDAT ; Line 3 xor eax, eax cmp DWORD PTR _n$[esp-4], eax setne al ; Line 4 ret 0 _ne1 ENDP _TEXT ENDS PUBLIC _main ; Function compile flags: /Ogtpy ; COMDAT _main _TEXT SEGMENT _main PROC ; COMDAT ; Line 14 call _rand call _rand call _rand xor eax, eax ret 0 _main ENDP _TEXT ENDS END </code></pre> <p><code>ne2()</code> which used the <code>&lt;</code>, <code>&gt;</code> and <code>||</code> operators is <strong>clearly</strong> more expensive. <code>ne1()</code> and <code>ne3()</code> which use the <code>==</code> and <code>!=</code> operators respectively, are terser and equivalent.</p> <p>Visual Studio 2011 is <em>in beta</em>. I would consider this as a bug. My tests with two other compilers namely <em>gcc 4.6.2</em> and <em>clang 3.2</em>, with the <code>O2</code> optimization switch yielded the exact same assembly for all three tests (that I had) on my Windows 7 box. Here's a summary:</p> <pre><code>$ cat ne.c #include &lt;stdbool.h&gt; bool ne1(int n) { return n != 0; } bool ne2(int n) { return n &lt; 0 || n &gt; 0; } bool ne3(int n) { return !(n != 0); } int main() {} </code></pre> <p>yields with gcc:</p> <pre><code>_ne1: LFB0: .cfi_startproc movl 4(%esp), %eax testl %eax, %eax setne %al ret .cfi_endproc LFE0: .p2align 2,,3 .globl _ne2 .def _ne2; .scl 2; .type 32; .endef _ne2: LFB1: .cfi_startproc movl 4(%esp), %edx testl %edx, %edx setne %al ret .cfi_endproc LFE1: .p2align 2,,3 .globl _ne3 .def _ne3; .scl 2; .type 32; .endef _ne3: LFB2: .cfi_startproc movl 4(%esp), %ecx testl %ecx, %ecx sete %al ret .cfi_endproc LFE2: .def ___main; .scl 2; .type 32; .endef .section .text.startup,"x" .p2align 2,,3 .globl _main .def _main; .scl 2; .type 32; .endef _main: LFB3: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 andl $-16, %esp call ___main xorl %eax, %eax leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc LFE3: </code></pre> <p>and with clang: </p> <pre><code> .def _ne1; .scl 2; .type 32; .endef .text .globl _ne1 .align 16, 0x90 _ne1: cmpl $0, 4(%esp) setne %al movzbl %al, %eax ret .def _ne2; .scl 2; .type 32; .endef .globl _ne2 .align 16, 0x90 _ne2: cmpl $0, 4(%esp) setne %al movzbl %al, %eax ret .def _ne3; .scl 2; .type 32; .endef .globl _ne3 .align 16, 0x90 _ne3: cmpl $0, 4(%esp) sete %al movzbl %al, %eax ret .def _main; .scl 2; .type 32; .endef .globl _main .align 16, 0x90 _main: pushl %ebp movl %esp, %ebp calll ___main xorl %eax, %eax popl %ebp ret </code></pre> <p><strong><em>My suggestion would be to file this as a bug with <a href="http://connect.microsoft.com/visualstudio" rel="noreferrer">Microsoft Connect</a>.</em></strong></p> <p>Note: I compiled them as C source since I don't think using the corresponding C++ compiler would make any significant change here.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload