Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -966,7 +966,7 @@ return nullptr; llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size); - Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy); + Addr = EmitCastToVoidPtrInAllocaAddrSpace(Addr); llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr}); C->setDoesNotThrow(); @@ -974,7 +974,7 @@ } void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) { - Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy); + Addr = EmitCastToVoidPtrInAllocaAddrSpace(Addr); llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr}); C->setDoesNotThrow(); Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -59,6 +59,18 @@ return Builder.CreateBitCast(value, destType); } +llvm::Value * +CodeGenFunction::EmitCastToVoidPtrInAllocaAddrSpace(llvm::Value *V) { + if (V->getType()->getPointerAddressSpace() != + CGM.getDataLayout().getAllocaAddrSpace()) { + return getTargetHooks().performAddrSpaceCast( + *this, V, getASTAllocaAddressSpace(), LangAS::Default, AllocaInt8PtrTy, + /*non-null*/ true); + } else { + return Builder.CreateBitCast(V, AllocaInt8PtrTy); + } +} + /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2072,6 +2072,9 @@ /// Emit a cast to void* in the appropriate address space. llvm::Value *EmitCastToVoidPtr(llvm::Value *value); + /// Emit a cast to void* in alloca address space. + llvm::Value *EmitCastToVoidPtrInAllocaAddrSpace(llvm::Value *V); + /// EvaluateExprAsBool - Perform the usual unary conversions on the specified /// expression and compare the result against zero, returning an Int1Ty value. llvm::Value *EvaluateExprAsBool(const Expr *E); Index: test/CodeGenCXX/amdgcn_declspec_get.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/amdgcn_declspec_get.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm -O3 -fdeclspec \ +// RUN: -disable-llvm-passes -o - %s | FileCheck %s + +int get_x(); + +struct A { + __declspec(property(get = _get_x)) int x; + static int _get_x(void) { + return get_x(); + }; +}; + +extern const A a; + +// CHECK-LABEL: define void @_Z4testv() +// CHECK: %i = alloca i32, align 4, addrspace(5) +// CHECK: %[[ii:.*]] = addrspacecast i32 addrspace(5)* %i to i32* +// CHECK: %[[cast1:.*]] = addrspacecast i32* %[[ii]] to i8 addrspace(5)* +// CHECK: call void @llvm.lifetime.start.p5i8(i64 4, i8 addrspace(5)* %[[cast1]]) +// CHECK: %call = call i32 @_ZN1A6_get_xEv() +// CHECK: store i32 %call, i32* %[[ii]] +// CHECK: %[[cast2:.*]] = addrspacecast i32* %[[ii]] to i8 addrspace(5)* +// CHECK: call void @llvm.lifetime.end.p5i8(i64 4, i8 addrspace(5)* %[[cast2]]) +void test() +{ + int i = a.x; +}