Hi Chris,<br><br><div class="gmail_quote">On Fri, Apr 13, 2012 at 10:23 AM, Chris Lattner <span dir="ltr"><<a href="mailto:clattner@apple.com">clattner@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Apr 12, 2012, at 11:31 PM, Richard Smith wrote:<br>
> Author: rsmith<br>
> Date: Fri Apr 13 01:31:38 2012<br>
> New Revision: 154659<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=154659&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=154659&view=rev</a><br>
> Log:<br>
> Implement __atomic_fetch_nand and __atomic_nand_fetch to complete our set of<br>
> GNU __atomic builtins.<br>
<br>
</div>I'm not opposed to this, but there is a reason that we didn't support the nand builtins.  Old versions of gcc implemented nand "wrong", and then they fixed it in more recent versions of gcc.  Please make sure that this is following gcc mainline.<br>
</blockquote></div><br><div>The behavior is as follows:</div><div><br></div><div>* gcc prior to 4.4 implemented __sync_fetch_and_nand as *x = ~*x & y.</div><div>* gcc from 4.4 onwards implements __sync_fetch_and_nand as *x = ~(*x & y).</div>
<div>* gcc added __atomic_fetch_nand in 4.7. It implements the ~(*x & y) behavior and has never had the ~*x & y bug.</div><div>* clang implements __atomic_fetch_nand but does not impement __sync_fetch_and_nand.</div>
<div><br></div><div>That all seems fine to me. However...</div><div><br></div><div>Clang lowers __atomic_fetch_nand(&p, 123, 5) to:</div><div><br></div><div><div>  %0 = atomicrmw nand i32* @p, i32 123 seq_cst</div></div>
<div><br></div><div>... which is documented as performing *x = ~(*x & y) operation, but actually performs *x = ~*x & y (at least on x86):</div><div><br></div><div><div>        movl    $123, %ecx</div><div>.LBB0_1:                                # %entry</div>
<div>        movl    p, %eax</div><div>        movl    %eax, %edx</div><div>        notl    %edx</div><div>        andl    %ecx, %edx</div><div>        lock</div><div>        cmpxchgl        %edx, p</div><div>        jne     .LBB0_1</div>
</div><div><br></div><div>So, is this an LLVM documentation bug (in which case I'll remove these builtins again, since LLVM doesn't provide support for them) or is it an LLVM codegen bug?</div><div><br></div><div>
Thanks!</div><div>Richard</div>