diff options
| author | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-07-15 11:58:10 +0000 |
|---|---|---|
| committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-07-15 11:58:10 +0000 |
| commit | 960ff0810da8fe7bb0059acdc4fdc397440eb245 (patch) | |
| tree | 4f469ceb256d28b2dab49b078cea0caf434db095 /clang/lib/CodeGen | |
| parent | 224816ba169923f4ac9a1e8ac28ce10b991db239 (diff) | |
| download | bcm5719-llvm-960ff0810da8fe7bb0059acdc4fdc397440eb245.tar.gz bcm5719-llvm-960ff0810da8fe7bb0059acdc4fdc397440eb245.zip | |
[OpenCL][PR41727] Prevent ICE on global dtors
Pass NULL to pointer arg of __cxa_atexit if addr space
is not matching with its param. This doesn't align yet
with how dtors are generated that should be changed too.
Differential Revision: https://reviews.llvm.org/D62413
llvm-svn: 366059
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 21 | ||||
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 5 |
4 files changed, 41 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index b03e3faeb33..1c7c6fb5413 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/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,9 +119,22 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, CXXDestructorDecl *Dtor = Record->getDestructor(); Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete)); - Argument = llvm::ConstantExpr::getBitCast( - Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo()); - + if (CGF.getContext().getLangOpts().OpenCL) { + auto DestAS = + CGM.getTargetCodeGenInfo().getAddrSpaceOfCxaAtexitPtrParam(); + auto DestTy = CGF.getTypes().ConvertType(Type)->getPointerTo( + CGM.getContext().getTargetAddressSpace(DestAS)); + auto SrcAS = D.getType().getQualifiers().getAddressSpace(); + if (DestAS == SrcAS) + Argument = llvm::ConstantExpr::getBitCast(Addr.getPointer(), DestTy); + else + // FIXME: On addr space mismatch we are passing NULL. The generation + // of the global destructor function should be adjusted accordingly. + Argument = llvm::ConstantPointerNull::get(DestTy); + } else { + Argument = llvm::ConstantExpr::getBitCast( + Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo()); + } // Otherwise, the standard logic requires a helper function. } else { Func = CodeGenFunction(CGM) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ea52f0c61fc..ba501d645c2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3577,8 +3577,12 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, 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; } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index a12f08fbe9a..cb22239559a 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2284,8 +2284,19 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, 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); @@ -2294,12 +2305,6 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, 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 @@ -2309,7 +2314,7 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, 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); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index d7e9eee9c5b..e1e90e73cb5 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -267,6 +267,11 @@ public: LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy) const; + /// Get address space of pointer parameter for __cxa_atexit. + virtual LangAS getAddrSpaceOfCxaAtexitPtrParam() const { + return LangAS::Default; + } + /// Get the syncscope used in LLVM IR. virtual llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts, SyncScope Scope, |

