]> granicus.if.org Git - clang/commitdiff
CodeGen: Make atomic operations play nice with address spaces
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 22 Nov 2014 10:44:12 +0000 (10:44 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 22 Nov 2014 10:44:12 +0000 (10:44 +0000)
We were being a little sloppy with our pointer/address space casts.

This fixes PR21643.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222615 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGAtomic.cpp
test/CodeGen/atomic-ops.c

index f4d90a6dfd40852fd76bc8107523dfe33b0f9ed9..c83ae13b68279dbccbd507c7ffd6998a719d5ec7 100644 (file)
@@ -765,13 +765,15 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
                 E->getOp() == AtomicExpr::AO__atomic_load ||
                 E->getOp() == AtomicExpr::AO__atomic_load_n;
 
-  llvm::Type *IPtrTy =
-      llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();
+  llvm::Type *ITy =
+      llvm::IntegerType::get(getLLVMContext(), Size * 8);
   llvm::Value *OrigDest = Dest;
-  Ptr = Builder.CreateBitCast(Ptr, IPtrTy);
-  if (Val1) Val1 = Builder.CreateBitCast(Val1, IPtrTy);
-  if (Val2) Val2 = Builder.CreateBitCast(Val2, IPtrTy);
-  if (Dest && !E->isCmpXChg()) Dest = Builder.CreateBitCast(Dest, IPtrTy);
+  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 (Dest && !E->isCmpXChg())
+    Dest = Builder.CreateBitCast(Dest, ITy->getPointerTo());
 
   if (isa<llvm::ConstantInt>(Order)) {
     int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
index 7bc45b6135ca35d434f672859e748b72a754e685..08731aaaded827ba59f55cfb597e2113821edbcc 100644 (file)
@@ -543,4 +543,19 @@ void EMIT_ALL_THE_THINGS(int *ptr, int *ptr2, int new, _Bool weak, int success,
   // CHECK: = cmpxchg weak {{.*}} seq_cst seq_cst
 }
 
+int PR21643() {
+  return __atomic_or_fetch((int __attribute__((address_space(257))) *)0x308, 1,
+                           __ATOMIC_RELAXED);
+  // CHECK: %[[atomictmp:.*]] = alloca i32, align 4
+  // CHECK: %[[atomicdst:.*]] = alloca i32, align 4
+  // CHECK: store i32 1, i32* %[[atomictmp]]
+  // CHECK: %[[one:.*]] = load i32* %[[atomictmp]], align 4
+  // CHECK: %[[old:.*]] = atomicrmw or i32 addrspace(257)* inttoptr (i32 776 to i32 addrspace(257)*), i32 %[[one]] monotonic
+  // CHECK: %[[new:.*]] = or i32 %[[old]], %[[one]]
+  // CHECK: store i32 %[[new]], i32* %[[atomicdst]], align 4
+  // CHECK: %[[ret:.*]] = load i32* %[[atomicdst]], align 4
+  // CHECK: ret i32 %[[ret]]
+
+}
+
 #endif