Hi,<div><br></div><div><div class="gmail_quote">On Fri, Apr 13, 2012 at 1:41 PM, 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 13, 2012, at 1:20 PM, Richard Smith wrote:<br>> Clang lowers __atomic_fetch_nand(&p, 123, 5) to:<br>
><br>
> %0 = atomicrmw nand i32* @p, i32 123 seq_cst<br>
><br>
> ... which is documented as performing *x = ~(*x & y) operation, but actually performs *x = ~*x & y (at least on x86):<br>
<br>
</div>Sounds like a (bad!) codegen bug. It probably dates back to when we did support __sync_fetch_and_nand. I think that GCC 4.4 is old enough that we could add support for __sync_fetch_and_nand in, with the proper semantics (and fix the codegen bug!)</blockquote>
<div><br></div><div>The attached patch fixes the codegen bug. With this,</div><div><div><br></div><div> %18 = atomicrmw nand i32* %val2, i32 1401 monotonic</div><div> store i32 %18, i32* %old</div></div><div><br></div><div>
generates:</div><div><br></div><div><div> movl $1401, %edx # imm = 0x579</div><div> .align 16, 0x90</div><div>.LBB0_23: # %entry</div><div> # =>This Inner Loop Header: Depth=1</div>
<div> movl 28(%esp), %ecx</div><div> andl %edx, %ecx</div><div> notl %ecx</div><div> movl %ecx, %eax</div><div> lock</div><div> cmpxchgl %ecx, 28(%esp)</div><div>
jne .LBB0_23</div></div><div><div># BB#24: # %entry</div><div> movl %eax, 12(%esp)</div></div><div><br></div><div>and:</div><div><br></div><div><div> %19 = atomicrmw nand i64* %temp64, i64 17361641481138401520 monotonic</div>
<div> store i64 %19, i64* %temp64</div></div><div><br></div><div>generates:</div><div><br></div><div><div> movl $-252645136, %ebp # imm = 0xFFFFFFFFF0F0F0F0</div><div> movl (%esp), %eax</div><div>
movl 4(%esp), %edx</div><div> .align 16, 0x90</div><div>.LBB0_25: # %entry</div><div> # =>This Inner Loop Header: Depth=1</div><div>
movl %eax, %esi</div><div> movl %edx, %edi</div><div> movl %esi, %ebx</div><div> andl %ebp, %ebx</div><div> movl %edi, %ecx</div><div> andl %ebp, %ecx</div><div>
notl %ebx</div><div> notl %ecx</div><div> lock</div><div> cmpxchg8b (%esp)</div><div> jne .LBB0_25</div><div># BB#26: # %entry</div><div> movl %edi, 4(%esp)</div>
</div><div><br></div><div>-- Richard</div></div></div>