[cfe-commits] r154659 - in /cfe/trunk: include/clang/Basic/Builtins.def lib/AST/Expr.cpp lib/CodeGen/CGExpr.cpp lib/Sema/SemaChecking.cpp test/CodeGen/atomic-ops.c
Richard Smith
richard at metafoo.co.uk
Fri Apr 13 13:20:50 PDT 2012
Hi Chris,
On Fri, Apr 13, 2012 at 10:23 AM, Chris Lattner <clattner at apple.com> wrote:
> On Apr 12, 2012, at 11:31 PM, Richard Smith wrote:
> > Author: rsmith
> > Date: Fri Apr 13 01:31:38 2012
> > New Revision: 154659
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=154659&view=rev
> > Log:
> > Implement __atomic_fetch_nand and __atomic_nand_fetch to complete our
> set of
> > GNU __atomic builtins.
>
> 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.
>
The behavior is as follows:
* gcc prior to 4.4 implemented __sync_fetch_and_nand as *x = ~*x & y.
* gcc from 4.4 onwards implements __sync_fetch_and_nand as *x = ~(*x & y).
* gcc added __atomic_fetch_nand in 4.7. It implements the ~(*x & y)
behavior and has never had the ~*x & y bug.
* clang implements __atomic_fetch_nand but does not impement
__sync_fetch_and_nand.
That all seems fine to me. However...
Clang lowers __atomic_fetch_nand(&p, 123, 5) to:
%0 = atomicrmw nand i32* @p, i32 123 seq_cst
... which is documented as performing *x = ~(*x & y) operation, but
actually performs *x = ~*x & y (at least on x86):
movl $123, %ecx
.LBB0_1: # %entry
movl p, %eax
movl %eax, %edx
notl %edx
andl %ecx, %edx
lock
cmpxchgl %edx, p
jne .LBB0_1
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?
Thanks!
Richard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120413/44109f95/attachment.html>
More information about the cfe-commits
mailing list