Thanks, fixed in r154845.<br><br><div class="gmail_quote">On Mon, Apr 16, 2012 at 11:07 AM, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@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"><br>
On Apr 13, 2012, at 3:47 PM, Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
<br>
> Author: rsmith<br>
> Date: Fri Apr 13 17:47:00 2012<br>
> New Revision: 154705<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=154705&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=154705&view=rev</a><br>
> Log:<br>
> Fix X86 codegen for 'atomicrmw nand' to generate *x = ~(*x & y), not *x = ~*x & y.<br>
<br>
</div>The libc++ atomics tests are deadlocking now, which seems to have started with this change…<br>
<br>
I'm seeing deadlocks with at least:<br>
<br>
test/atomics/atomics.types.generic/integral.pass.cpp failed at run time<br>
test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp<br>
test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp<br>
test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp<br>
test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp<br>
test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp<br>
test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp<br>
<br>
        - Doug<br>
<div class="HOEnZb"><div class="h5"><br>
> Modified:<br>
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
>    llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
>    llvm/trunk/test/CodeGen/X86/atomic_op.ll<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=154705&r1=154704&r2=154705&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=154705&r1=154704&r2=154705&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Apr 13 17:47:00 2012<br>
> @@ -11298,14 +11298,15 @@<br>
>                                                        unsigned notOpc,<br>
>                                                        unsigned EAXreg,<br>
>                                                  const TargetRegisterClass *RC,<br>
> -                                                       bool invSrc) const {<br>
> +                                                       bool Invert) const {<br>
>   // For the atomic bitwise operator, we generate<br>
>   //   thisMBB:<br>
>   //   newMBB:<br>
>   //     ld  t1 = [bitinstr.addr]<br>
>   //     op  t2 = t1, [bitinstr.val]<br>
> +  //     not t3 = t2  (if Invert)<br>
>   //     mov EAX = t1<br>
> -  //     lcs dest = [bitinstr.addr], t2  [EAX is implicit]<br>
> +  //     lcs dest = [bitinstr.addr], t3  [EAX is implicit]<br>
>   //     bz  newMBB<br>
>   //     fallthrough -->nextMBB<br>
>   const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();<br>
> @@ -11353,13 +11354,6 @@<br>
>   for (int i=0; i <= lastAddrIndx; ++i)<br>
>     (*MIB).addOperand(*argOpers[i]);<br>
><br>
> -  unsigned tt = F->getRegInfo().createVirtualRegister(RC);<br>
> -  if (invSrc) {<br>
> -    MIB = BuildMI(newMBB, dl, TII->get(notOpc), tt).addReg(t1);<br>
> -  }<br>
> -  else<br>
> -    tt = t1;<br>
> -<br>
>   unsigned t2 = F->getRegInfo().createVirtualRegister(RC);<br>
>   assert((argOpers[valArgIndx]->isReg() ||<br>
>           argOpers[valArgIndx]->isImm()) &&<br>
> @@ -11368,16 +11362,23 @@<br>
>     MIB = BuildMI(newMBB, dl, TII->get(regOpc), t2);<br>
>   else<br>
>     MIB = BuildMI(newMBB, dl, TII->get(immOpc), t2);<br>
> -  MIB.addReg(tt);<br>
> +  MIB.addReg(t1);<br>
>   (*MIB).addOperand(*argOpers[valArgIndx]);<br>
><br>
> +  unsigned t3 = F->getRegInfo().createVirtualRegister(RC);<br>
> +  if (Invert) {<br>
> +    MIB = BuildMI(newMBB, dl, TII->get(notOpc), t3).addReg(t2);<br>
> +  }<br>
> +  else<br>
> +    t3 = t2;<br>
> +<br>
>   MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), EAXreg);<br>
> -  MIB.addReg(t1);<br>
> +  MIB.addReg(t3);<br>
><br>
>   MIB = BuildMI(newMBB, dl, TII->get(CXchgOpc));<br>
>   for (int i=0; i <= lastAddrIndx; ++i)<br>
>     (*MIB).addOperand(*argOpers[i]);<br>
> -  MIB.addReg(t2);<br>
> +  MIB.addReg(t3);<br>
>   assert(bInstr->hasOneMemOperand() && "Unexpected number of memoperand");<br>
>   (*MIB).setMemRefs(bInstr->memoperands_begin(),<br>
>                     bInstr->memoperands_end());<br>
> @@ -11400,7 +11401,7 @@<br>
>                                                        unsigned regOpcH,<br>
>                                                        unsigned immOpcL,<br>
>                                                        unsigned immOpcH,<br>
> -                                                       bool invSrc) const {<br>
> +                                                       bool Invert) const {<br>
>   // For the atomic bitwise operator, we generate<br>
>   //   thisMBB (instructions are in pairs, except cmpxchg8b)<br>
>   //     ld t1,t2 = [bitinstr.addr]<br>
> @@ -11408,6 +11409,7 @@<br>
>   //     out1, out2 = phi (thisMBB, t1/t2) (newMBB, t3/t4)<br>
>   //     op  t5, t6 <- out1, out2, [bitinstr.val]<br>
>   //      (for SWAP, substitute:  mov t5, t6 <- [bitinstr.val])<br>
> +  //     neg t7, t8 < t5, t6  (if Invert)<br>
>   //     mov ECX, EBX <- t5, t6<br>
>   //     mov EAX, EDX <- t1, t2<br>
>   //     cmpxchg8b [bitinstr.addr]  [EAX, EDX, EBX, ECX implicit]<br>
> @@ -11491,16 +11493,9 @@<br>
>     .addReg(t2).addMBB(thisMBB).addReg(t4).addMBB(newMBB);<br>
><br>
>   // The subsequent operations should be using the destination registers of<br>
> -  //the PHI instructions.<br>
> -  if (invSrc) {<br>
> -    t1 = F->getRegInfo().createVirtualRegister(RC);<br>
> -    t2 = F->getRegInfo().createVirtualRegister(RC);<br>
> -    MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t1).addReg(dest1Oper.getReg());<br>
> -    MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t2).addReg(dest2Oper.getReg());<br>
> -  } else {<br>
> -    t1 = dest1Oper.getReg();<br>
> -    t2 = dest2Oper.getReg();<br>
> -  }<br>
> +  // the PHI instructions.<br>
> +  t1 = dest1Oper.getReg();<br>
> +  t2 = dest2Oper.getReg();<br>
><br>
>   int valArgIndx = lastAddrIndx + 1;<br>
>   assert((argOpers[valArgIndx]->isReg() ||<br>
> @@ -11527,15 +11522,26 @@<br>
>     MIB.addReg(t2);<br>
>   (*MIB).addOperand(*argOpers[valArgIndx + 1]);<br>
><br>
> +  unsigned t7, t8;<br>
> +  if (Invert) {<br>
> +    t7 = F->getRegInfo().createVirtualRegister(RC);<br>
> +    t8 = F->getRegInfo().createVirtualRegister(RC);<br>
> +    MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t7).addReg(t5);<br>
> +    MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t8).addReg(t6);<br>
> +  } else {<br>
> +    t7 = t5;<br>
> +    t8 = t6;<br>
> +  }<br>
> +<br>
>   MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EAX);<br>
>   MIB.addReg(t1);<br>
>   MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EDX);<br>
>   MIB.addReg(t2);<br>
><br>
>   MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::EBX);<br>
> -  MIB.addReg(t5);<br>
> +  MIB.addReg(t7);<br>
>   MIB = BuildMI(newMBB, dl, TII->get(TargetOpcode::COPY), X86::ECX);<br>
> -  MIB.addReg(t6);<br>
> +  MIB.addReg(t8);<br>
><br>
>   MIB = BuildMI(newMBB, dl, TII->get(X86::LCMPXCHG8B));<br>
>   for (int i=0; i <= lastAddrIndx; ++i)<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=154705&r1=154704&r2=154705&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=154705&r1=154704&r2=154705&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Fri Apr 13 17:47:00 2012<br>
> @@ -855,7 +855,7 @@<br>
>                                                     unsigned notOpc,<br>
>                                                     unsigned EAXreg,<br>
>                                               const TargetRegisterClass *RC,<br>
> -                                                    bool invSrc = false) const;<br>
> +                                                    bool Invert = false) const;<br>
><br>
>     MachineBasicBlock *EmitAtomicBit6432WithCustomInserter(<br>
>                                                     MachineInstr *BInstr,<br>
> @@ -864,7 +864,7 @@<br>
>                                                     unsigned regOpcH,<br>
>                                                     unsigned immOpcL,<br>
>                                                     unsigned immOpcH,<br>
> -                                                    bool invSrc = false) const;<br>
> +                                                    bool Invert = false) const;<br>
><br>
>     /// Utility function to emit atomic min and max.  It takes the min/max<br>
>     /// instruction to expand, the associated basic block, and the associated<br>
><br>
> Modified: llvm/trunk/test/CodeGen/X86/atomic_op.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/atomic_op.ll?rev=154705&r1=154704&r2=154705&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/atomic_op.ll?rev=154705&r1=154704&r2=154705&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/X86/atomic_op.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/X86/atomic_op.ll Fri Apr 13 17:47:00 2012<br>
> @@ -13,6 +13,7 @@<br>
>       %xort = alloca i32              ; <i32*> [#uses=2]<br>
>       %old = alloca i32               ; <i32*> [#uses=18]<br>
>       %temp = alloca i32              ; <i32*> [#uses=2]<br>
> +     %temp64 = alloca i64<br>
>       store i32 %argc, i32* %argc.addr<br>
>       store i8** %argv, i8*** %argv.addr<br>
>       store i32 0, i32* %val1<br>
> @@ -106,6 +107,20 @@<br>
>         ; CHECK: cmpxchgl<br>
>   %17 = cmpxchg i32* %val2, i32 1976, i32 1 monotonic<br>
>       store i32 %17, i32* %old<br>
> +        ; CHECK: andl<br>
> +        ; CHECK: notl<br>
> +        ; CHECK: lock<br>
> +        ; CHECK: cmpxchgl<br>
> +  %18 = atomicrmw nand i32* %val2, i32 1401 monotonic<br>
> +  store i32 %18, i32* %old<br>
> +        ; CHECK: andl<br>
> +        ; CHECK: andl<br>
> +        ; CHECK: notl<br>
> +        ; CHECK: notl<br>
> +        ; CHECK: lock<br>
> +        ; CHECK: cmpxchg8b<br>
> +  %19 = atomicrmw nand i64* %temp64, i64 17361641481138401520 monotonic<br>
> +  store i64 %19, i64* %temp64<br>
>       ret void<br>
> }<br>
><br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
</div></div></blockquote></div><br>