diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index daac174..7f39029 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -778,8 +778,12 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
   llvm::Value *OrigDest = GetDest();
   Ptr = Builder.CreateBitCast(
       Ptr, ITy->getPointerTo(Ptr->getType()->getPointerAddressSpace()));
-  if (Val1) Val1 = Builder.CreateBitCast(Val1, ITy->getPointerTo());
-  if (Val2) Val2 = Builder.CreateBitCast(Val2, ITy->getPointerTo());
+  if (Val1)
+    Val1 = Builder.CreateBitCast(
+        Val1, ITy->getPointerTo(Val1->getType()->getPointerAddressSpace()));
+  if (Val2)
+    Val2 = Builder.CreateBitCast(
+        Val2, ITy->getPointerTo(Val2->getType()->getPointerAddressSpace()));
   if (Dest && !E->isCmpXChg())
     Dest = Builder.CreateBitCast(Dest, ITy->getPointerTo());
 
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index f4e33c6..944812e 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1407,8 +1407,17 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,
           Ty = ByValType;
         else if (Form == Arithmetic)
           Ty = Context.getPointerDiffType();
-        else
-          Ty = Context.getPointerType(ValType.getUnqualifiedType());
+        else {
+          Expr *ValArg = TheCall->getArg(i);
+          unsigned AS = 0;
+          // Keep address space of non-atomic pointer type.
+          if (const PointerType *PtrTy =
+                  ValArg->getType()->getAs<PointerType>()) {
+            AS = PtrTy->getPointeeType().getAddressSpace();
+          }
+          Ty = Context.getPointerType(
+              Context.getAddrSpaceQualType(ValType.getUnqualifiedType(), AS));
+        }
         break;
       case 2:
         // The third argument to compare_exchange / GNU exchange is a
diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c
index e21c3fd..b502c3a 100644
--- a/test/Sema/atomic-ops.c
+++ b/test/Sema/atomic-ops.c
@@ -85,6 +85,9 @@ _Static_assert(__atomic_always_lock_free(4, &i64), "");
 _Static_assert(!__atomic_always_lock_free(8, &i32), "");
 _Static_assert(__atomic_always_lock_free(8, &i64), "");
 
+#define _AS1 __attribute__((address_space(1)))
+#define _AS2 __attribute__((address_space(2)))
+
 void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d,
        int *I, int **P, float *D, struct S *s1, struct S *s2) {
   __c11_atomic_init(I, 5); // expected-error {{pointer to _Atomic}}
@@ -164,6 +167,9 @@ void f(_Atomic(int) *i, _Atomic(int*) *p, _Atomic(float) *d,
   _Bool cmpexch_8 = __atomic_compare_exchange(I, P, I, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{; dereference with *}}
   _Bool cmpexch_9 = __atomic_compare_exchange(I, I, I, 0, memory_order_seq_cst, memory_order_seq_cst);
 
+  // Pointers to different address spaces are allowed.
+  _Bool cmpexch_10 = __c11_atomic_compare_exchange_strong((_Atomic int _AS1 *)0x308, (int _AS2 *)0x309, 1, memory_order_seq_cst, memory_order_seq_cst);
+
   const volatile int flag_k = 0;
   volatile int flag = 0;
   (void)(int)__atomic_test_and_set(&flag_k, memory_order_seq_cst); // expected-warning {{passing 'const volatile int *' to parameter of type 'volatile void *'}}
