Index: clang/lib/CodeGen/CGCUDANV.cpp =================================================================== --- clang/lib/CodeGen/CGCUDANV.cpp +++ clang/lib/CodeGen/CGCUDANV.cpp @@ -375,6 +375,19 @@ CtorBuilder.SetInsertPoint(CtorEntryBB); + // Create destructor and register it with atexit() the way NVCC does it. Doing + // it during regular destructor phase worked in CUDA before 9.2 but results in + // double-free in 9.2. + if (llvm::Function *CleanupFn = makeModuleDtorFunction()) { + // extern "C" int atexit(void (*f)(void)); + llvm::FunctionType *AtExitTy = + llvm::FunctionType::get(IntTy, CleanupFn->getType(), false); + llvm::Constant *AtExitFunc = + CGM.CreateRuntimeFunction(AtExitTy, "atexit", llvm::AttributeList(), + /*Local=*/true); + CtorBuilder.CreateCall(AtExitFunc, CleanupFn); + } + const char *FatbinConstantName; const char *FatbinSectionName; const char *ModuleIDSectionName; @@ -530,19 +543,6 @@ CtorBuilder.CreateCall(RegisterLinkedBinaryFunc, Args); } - // Create destructor and register it with atexit() the way NVCC does it. Doing - // it during regular destructor phase worked in CUDA before 9.2 but results in - // double-free in 9.2. - if (llvm::Function *CleanupFn = makeModuleDtorFunction()) { - // extern "C" int atexit(void (*f)(void)); - llvm::FunctionType *AtExitTy = - llvm::FunctionType::get(IntTy, CleanupFn->getType(), false); - llvm::Constant *AtExitFunc = - CGM.CreateRuntimeFunction(AtExitTy, "atexit", llvm::AttributeList(), - /*Local=*/true); - CtorBuilder.CreateCall(AtExitFunc, CleanupFn); - } - CtorBuilder.CreateRetVoid(); return ModuleCtorFunc; }