summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAnastasia Stulova <anastasia.stulova@arm.com>2019-07-15 11:58:10 +0000
committerAnastasia Stulova <anastasia.stulova@arm.com>2019-07-15 11:58:10 +0000
commit960ff0810da8fe7bb0059acdc4fdc397440eb245 (patch)
tree4f469ceb256d28b2dab49b078cea0caf434db095 /clang/lib/CodeGen
parent224816ba169923f4ac9a1e8ac28ce10b991db239 (diff)
downloadbcm5719-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.cpp20
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp8
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp21
-rw-r--r--clang/lib/CodeGen/TargetInfo.h5
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,
OpenPOWER on IntegriCloud