diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index c2e4f1f816a..d78482673b0 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -615,6 +615,7 @@ namespace ISD {
     ATOMIC_LOAD_AND,
     ATOMIC_LOAD_OR,
     ATOMIC_LOAD_XOR,
+    ATOMIC_LOAD_NAND,
     ATOMIC_LOAD_MIN,
     ATOMIC_LOAD_MAX,
     ATOMIC_LOAD_UMIN,
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 633063eb48f..18c42e41f8a 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -302,6 +302,11 @@ def int_atomic_load_xor  : Intrinsic<[llvm_anyint_ty,
                                   LLVMMatchType<0>],
                                  [IntrWriteArgMem]>,
                            GCCBuiltin<"__sync_fetch_and_xor">;
+def int_atomic_load_nand : Intrinsic<[llvm_anyint_ty,
+                                  LLVMPointerType<LLVMMatchType<0>>,
+                                  LLVMMatchType<0>],
+                                 [IntrWriteArgMem]>,
+                           GCCBuiltin<"__sync_fetch_and_nand">;
 def int_atomic_load_min  : Intrinsic<[llvm_anyint_ty,
                                    LLVMPointerType<LLVMMatchType<0>>,
                                    LLVMMatchType<0>],
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index dd5a350f49d..87bb1dbf142 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1254,6 +1254,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   case ISD::ATOMIC_LOAD_AND:
   case ISD::ATOMIC_LOAD_OR:
   case ISD::ATOMIC_LOAD_XOR:
+  case ISD::ATOMIC_LOAD_NAND:
   case ISD::ATOMIC_LOAD_MIN:
   case ISD::ATOMIC_LOAD_MAX:
   case ISD::ATOMIC_LOAD_UMIN:
@@ -4285,6 +4286,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
   case ISD::ATOMIC_LOAD_AND:
   case ISD::ATOMIC_LOAD_OR:
   case ISD::ATOMIC_LOAD_XOR:
+  case ISD::ATOMIC_LOAD_NAND:
   case ISD::ATOMIC_LOAD_MIN:
   case ISD::ATOMIC_LOAD_MAX:
   case ISD::ATOMIC_LOAD_UMIN:
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 4f577fc269a..bca5e756d45 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2995,6 +2995,7 @@ SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain,
   assert((   Opcode == ISD::ATOMIC_LAS || Opcode == ISD::ATOMIC_LSS
           || Opcode == ISD::ATOMIC_SWAP || Opcode == ISD::ATOMIC_LOAD_AND
           || Opcode == ISD::ATOMIC_LOAD_OR || Opcode == ISD::ATOMIC_LOAD_XOR
+          || Opcode == ISD::ATOMIC_LOAD_NAND 
           || Opcode == ISD::ATOMIC_LOAD_MIN || Opcode == ISD::ATOMIC_LOAD_MAX
           || Opcode == ISD::ATOMIC_LOAD_UMIN || Opcode == ISD::ATOMIC_LOAD_UMAX) 
          && "Invalid Atomic Op");
@@ -4406,6 +4407,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
   case ISD::ATOMIC_LOAD_AND:  return "AtomicLoadAnd";
   case ISD::ATOMIC_LOAD_OR:   return "AtomicLoadOr";
   case ISD::ATOMIC_LOAD_XOR:  return "AtomicLoadXor";
+  case ISD::ATOMIC_LOAD_NAND: return "AtomicLoadNand";
   case ISD::ATOMIC_LOAD_MIN:  return "AtomicLoadMin";
   case ISD::ATOMIC_LOAD_MAX:  return "AtomicLoadMax";
   case ISD::ATOMIC_LOAD_UMIN: return "AtomicLoadUMin";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index f1dc64d3296..a55f904b218 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3526,6 +3526,8 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR);
   case Intrinsic::atomic_load_xor:
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR);
+  case Intrinsic::atomic_load_nand:
+    return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND);
   case Intrinsic::atomic_load_min:
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN);
   case Intrinsic::atomic_load_max:
diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td
index b7fadd1d757..38a604653f5 100644
--- a/lib/Target/TargetSelectionDAG.td
+++ b/lib/Target/TargetSelectionDAG.td
@@ -367,6 +367,8 @@ def atomic_load_or  : SDNode<"ISD::ATOMIC_LOAD_OR" , STDAtomic2,
                          [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
 def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , STDAtomic2,
                          [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
+def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", STDAtomic2,
+                         [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
 def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", STDAtomic2,
                          [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
 def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", STDAtomic2,
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 53f42b9c0d9..11442b5fa58 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -5963,7 +5963,8 @@ MachineBasicBlock *
 X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
                                                        MachineBasicBlock *MBB,
                                                        unsigned regOpc,
-                                                       unsigned immOpc) {
+                                                       unsigned immOpc,
+                                                       bool invSrc) {
   // For the atomic bitwise operator, we generate
   //   thisMBB:
   //   newMBB:
@@ -6012,7 +6013,14 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
   MachineInstrBuilder MIB = BuildMI(newMBB, TII->get(X86::MOV32rm), t1);
   for (int i=0; i <= lastAddrIndx; ++i)
     (*MIB).addOperand(*argOpers[i]);
-  
+
+  unsigned tt = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+  if (invSrc) {
+    MIB = BuildMI(newMBB, TII->get(X86::NOT32r), tt).addReg(t1);
+  }
+  else 
+    tt = t1;
+
   unsigned t2 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
   assert(   (argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm())
          && "invalid operand");
@@ -6020,9 +6028,9 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
     MIB = BuildMI(newMBB, TII->get(regOpc), t2);
   else
     MIB = BuildMI(newMBB, TII->get(immOpc), t2);
-  MIB.addReg(t1);
+  MIB.addReg(tt);
   (*MIB).addOperand(*argOpers[valArgIndx]);
-  
+
   MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), X86::EAX);
   MIB.addReg(t1);
   
@@ -6286,6 +6294,9 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
   case X86::ATOMXOR32:
     return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::XOR32rr,
                                                        X86::XOR32ri);
+  case X86::ATOMNAND32:
+    return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::AND32rr,
+                                               X86::AND32ri, true);
   case X86::ATOMMIN32:
     return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVL32rr);
   case X86::ATOMMAX32:
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index c7a43a47a6c..f2b851e66e4 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -567,7 +567,8 @@ namespace llvm {
                                                     MachineInstr *BInstr,
                                                     MachineBasicBlock *BB,
                                                     unsigned regOpc,
-                                                    unsigned immOpc);
+                                                    unsigned immOpc,
+                                                    bool invSrc = false);
     
     /// Utility function to emit atomic min and max.  It takes the min/max
     // instruction to expand, the associated basic block, and the associated
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 4b8dc100b9e..2630834b6a3 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -2633,45 +2633,25 @@ let Constraints = "$val = $dst", Defs = [EFLAGS],
 def ATOMAND32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
                "#ATOMAND32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_and addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
-                  usesCustomDAGSchedInserter = 1 in {
 def ATOMOR32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
                "#ATOMOR32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_or addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
-                  usesCustomDAGSchedInserter = 1 in {
 def ATOMXOR32 : I<0, Pseudo,(outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
                "#ATOMXOR32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_xor addr:$ptr, GR32:$val))]>;
-}
+def ATOMNAND32 : I<0, Pseudo,(outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
+               "#ATOMXOR32 PSUEDO!", 
+               [(set GR32:$dst, (atomic_load_nand addr:$ptr, GR32:$val))]>;
 
-let Constraints = "$val = $dst", Defs = [EFLAGS],
-                  usesCustomDAGSchedInserter = 1 in {
 def ATOMMIN32: I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
                "#ATOMMIN32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_min addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
-                  usesCustomDAGSchedInserter = 1 in {
 def ATOMMAX32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
                "#ATOMMAX32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_max addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
-                  usesCustomDAGSchedInserter = 1 in {
 def ATOMUMIN32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
                "#ATOMUMIN32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_umin addr:$ptr, GR32:$val))]>;
-}
-
-let Constraints = "$val = $dst", Defs = [EFLAGS],
-                  usesCustomDAGSchedInserter = 1 in {
 def ATOMUMAX32: I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val),
                "#ATOMUMAX32 PSUEDO!", 
                [(set GR32:$dst, (atomic_load_umax addr:$ptr, GR32:$val))]>;