From d8cd8f7b6ea236d3fefec3e50738645cf470712b Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 22 Nov 2014 10:44:12 +0000 Subject: [PATCH] CodeGen: Make atomic operations play nice with address spaces We were being a little sloppy with our pointer/address space casts. This fixes PR21643. llvm-svn: 222615 --- clang/lib/CodeGen/CGAtomic.cpp | 14 ++++++++------ clang/test/CodeGen/atomic-ops.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index f4d90a6..c83ae13 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -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(Order)) { int ord = cast(Order)->getZExtValue(); diff --git a/clang/test/CodeGen/atomic-ops.c b/clang/test/CodeGen/atomic-ops.c index 7bc45b6..08731aa 100644 --- a/clang/test/CodeGen/atomic-ops.c +++ b/clang/test/CodeGen/atomic-ops.c @@ -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 -- 2.7.4