Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -965,6 +965,9 @@ if (!ShouldEmitLifetimeMarkers) return nullptr; + assert(Addr->getType()->getPointerAddressSpace() == + CGM.getDataLayout().getAllocaAddrSpace() && + "Pointer argument must be in alloca address space"); llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size); Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy); llvm::CallInst *C = @@ -974,6 +977,9 @@ } void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) { + assert(Addr->getType()->getPointerAddressSpace() == + CGM.getDataLayout().getAllocaAddrSpace() && + "Pointer argument must be in alloca address space"); Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy); llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr}); @@ -1175,8 +1181,10 @@ if (!Bypasses.IsBypassed(&D) && !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) { uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy); - emission.SizeForLifetimeMarkers = - EmitLifetimeStart(size, address.getPointer()); + auto *VoidPtr = address.getPointer(); + if (ShouldEmitLifetimeMarkers) + VoidPtr = EmitCastToVoidPtrInAllocaAddrSpace(VoidPtr); + emission.SizeForLifetimeMarkers = EmitLifetimeStart(size, VoidPtr); } } else { assert(!emission.useLifetimeMarkers()); 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 @@ -418,7 +418,7 @@ : Addr(addr.getPointer()), Size(size) {} void Emit(CodeGenFunction &CGF, Flags flags) override { - CGF.EmitLifetimeEnd(Size, Addr); + CGF.EmitLifetimeEnd(Size, CGF.EmitCastToVoidPtrInAllocaAddrSpace(Addr)); } }; @@ -2084,6 +2084,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; +}