Anastasia created this revision. Anastasia added a reviewer: rjmccall. Herald added subscribers: ebevhan, yaxunl.
Preserve address spaces of global objects while generating 'atexit' stub. https://reviews.llvm.org/D62413 Files: lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/ItaniumCXXABI.cpp test/CodeGenOpenCLCXX/atexit.cl
Index: test/CodeGenOpenCLCXX/atexit.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCLCXX/atexit.cl @@ -0,0 +1,11 @@ +//RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s + +struct S { + ~S(){}; +}; +S s; + +//CHECK-LABEL: define internal void @__cxx_global_var_init() +// call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.S addrspace(4)*)* @_ZNU3AS41SD1Ev to void (i8*)*), i8 addrspace(1)* getelementptr inbounds (%struct.S, %struct.S addrspace(1)* @s, i32 0, i32 0), i8 addrspace(1)* @__dso_handle) + +//declare i32 @__cxa_atexit(void (i8*)*, i8 addrspace(1)*, i8 addrspace(1)*) Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -2299,8 +2299,19 @@ llvm::Type *dtorTy = llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo(); + // Preserve address space of addr. + auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0; + auto AddrInt8PtrTy = + AddrAS ? CGF.Int8Ty->getPointerTo(AddrAS) : CGF.Int8PtrTy; + + // Create a variable that binds the atexit to this shared object. + llvm::Constant *handle = + CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle"); + auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts()); + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); + // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d); - llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy }; + llvm::Type *paramTys[] = {dtorTy, AddrInt8PtrTy, handle->getType()}; llvm::FunctionType *atexitTy = llvm::FunctionType::get(CGF.IntTy, paramTys, false); @@ -2309,12 +2320,6 @@ if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee())) fn->setDoesNotThrow(); - // Create a variable that binds the atexit to this shared object. - llvm::Constant *handle = - CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle"); - auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts()); - GV->setVisibility(llvm::GlobalValue::HiddenVisibility); - if (!addr) // addr is null when we are trying to register a dtor annotated with // __attribute__((destructor)) in a constructor function. Using null here is @@ -2324,7 +2329,7 @@ llvm::Value *args[] = {llvm::ConstantExpr::getBitCast( cast<llvm::Constant>(dtor.getCallee()), dtorTy), - llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy), + llvm::ConstantExpr::getBitCast(addr, AddrInt8PtrTy), handle}; CGF.EmitNounwindRuntimeCall(atexit, args); } Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -3533,8 +3533,12 @@ llvm::Constant * CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty, StringRef Name) { - auto *Ret = - GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), nullptr); + auto PtrTy = + getContext().getLangOpts().OpenCL + ? llvm::PointerType::get( + Ty, getContext().getTargetAddressSpace(LangAS::opencl_global)) + : llvm::PointerType::getUnqual(Ty); + auto *Ret = GetOrCreateLLVMGlobal(Name, PtrTy, nullptr); setDSOLocal(cast<llvm::GlobalValue>(Ret->stripPointerCasts())); return Ret; } Index: lib/CodeGen/CGDeclCXX.cpp =================================================================== --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -14,6 +14,7 @@ #include "CGCXXABI.h" #include "CGObjCRuntime.h" #include "CGOpenMPRuntime.h" +#include "TargetInfo.h" #include "clang/Basic/CodeGenOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Intrinsics.h" @@ -118,8 +119,17 @@ CXXDestructorDecl *Dtor = Record->getDestructor(); Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete)); - Argument = llvm::ConstantExpr::getBitCast( - Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo()); + // FIXME: A solution is needed for opencl_constant. We could create + // atexit_constant, but more generic solution would probably be to mangle + // address space? + auto DestTy = CGF.getTypes().ConvertType(Type)->getPointerTo( + CGM.getContext().getTargetAddressSpace(LangAS::opencl_global)); + auto SrcAS = D.getType().getQualifiers().getAddressSpace(); + if (LangAS::opencl_global == SrcAS) + Argument = llvm::ConstantExpr::getBitCast(Addr.getPointer(), DestTy); + else + Argument = CGM.getTargetCodeGenInfo().performAddrSpaceCast( + CGM, Addr.getPointer(), SrcAS, LangAS::opencl_global, DestTy); // Otherwise, the standard logic requires a helper function. } else {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits