summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp12
-rw-r--r--clang/lib/CodeGen/CGCUDANV.cpp11
-rw-r--r--clang/lib/CodeGen/CGCall.cpp3
-rw-r--r--clang/lib/CodeGen/CGClass.cpp4
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp140
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h10
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp48
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp14
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h19
-rw-r--r--clang/lib/CodeGen/CodeGenTBAA.cpp37
-rw-r--r--clang/lib/CodeGen/SanitizerMetadata.cpp18
12 files changed, 188 insertions, 138 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index eb40e446057f..7c4e35634e5d 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -788,6 +788,18 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
SI.registerCallbacks(PIC, &FAM);
PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
+ // Enable verify-debuginfo-preserve-each for new PM.
+ DebugifyEachInstrumentation Debugify;
+ DebugInfoPerPass DebugInfoBeforePass;
+ if (CodeGenOpts.EnableDIPreservationVerify) {
+ Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
+ Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
+
+ if (!CodeGenOpts.DIBugsReportFilePath.empty())
+ Debugify.setOrigDIVerifyBugsReportFilePath(
+ CodeGenOpts.DIBugsReportFilePath);
+ Debugify.registerCallbacks(PIC);
+ }
// Attempt to load pass plugins and register their callbacks with PB.
for (auto &PluginFN : CodeGenOpts.PassPlugins) {
auto PassPlugin = PassPlugin::Load(PluginFN);
diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp
index 6f2679cb15e4..a8bb0dd65d1a 100644
--- a/clang/lib/CodeGen/CGCUDANV.cpp
+++ b/clang/lib/CodeGen/CGCUDANV.cpp
@@ -212,8 +212,7 @@ static std::unique_ptr<MangleContext> InitDeviceMC(CodeGenModule &CGM) {
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
: CGCUDARuntime(CGM), Context(CGM.getLLVMContext()),
TheModule(CGM.getModule()),
- RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode ||
- CGM.getLangOpts().OffloadingNewDriver),
+ RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode),
DeviceMC(InitDeviceMC(CGM)) {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
@@ -1116,7 +1115,8 @@ void CGNVCUDARuntime::createOffloadingEntries() {
llvm::OpenMPIRBuilder OMPBuilder(CGM.getModule());
OMPBuilder.initialize();
- StringRef Section = "cuda_offloading_entries";
+ StringRef Section = CGM.getLangOpts().HIP ? "hip_offloading_entries"
+ : "cuda_offloading_entries";
for (KernelInfo &I : EmittedKernels)
OMPBuilder.emitOffloadingEntry(KernelHandles[I.Kernel],
getDeviceSideName(cast<NamedDecl>(I.D)), 0,
@@ -1171,10 +1171,11 @@ llvm::Function *CGNVCUDARuntime::finalizeModule() {
}
return nullptr;
}
- if (!(CGM.getLangOpts().OffloadingNewDriver && RelocatableDeviceCode))
+ if (CGM.getLangOpts().OffloadingNewDriver && RelocatableDeviceCode)
+ createOffloadingEntries();
+ else
return makeModuleCtorFunction();
- createOffloadingEntries();
return nullptr;
}
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4e26c35c6342..104a30dd6b25 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1931,6 +1931,9 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
FuncAttrs.addAttribute(llvm::Attribute::Convergent);
}
+ // TODO: NoUnwind attribute should be added for other GPU modes OpenCL, HIP,
+ // SYCL, OpenMP offload. AFAIK, none of them support exceptions in device
+ // code.
if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice) {
// Exceptions aren't supported in CUDA device code.
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 153f299a1c4b..cde31711a7db 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1783,14 +1783,14 @@ namespace {
StartIndex = FieldIndex;
} else if (StartIndex) {
EHStack.pushCleanup<SanitizeDtorFieldRange>(
- NormalAndEHCleanup, DD, StartIndex.getValue(), FieldIndex);
+ NormalAndEHCleanup, DD, StartIndex.value(), FieldIndex);
StartIndex = None;
}
}
void End() {
if (StartIndex)
EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD,
- StartIndex.getValue(), -1);
+ StartIndex.value(), -1);
}
};
} // end anonymous namespace
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 305040b01c08..091eb9da5af4 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -6717,11 +6717,9 @@ llvm::Value *CGOpenMPRuntime::emitNumTeamsForTargetDirective(
default:
break;
}
- } else if (DefaultNT == -1) {
- return nullptr;
}
- return Bld.getInt32(DefaultNT);
+ return llvm::ConstantInt::get(CGF.Int32Ty, DefaultNT);
}
static llvm::Value *getNumThreads(CodeGenFunction &CGF, const CapturedStmt *CS,
@@ -10189,9 +10187,8 @@ llvm::Function *CGOpenMPRuntime::getOrCreateUserDefinedMapperFunc(
return UDMMap.lookup(D);
}
-void CGOpenMPRuntime::emitTargetNumIterationsCall(
+llvm::Value *CGOpenMPRuntime::emitTargetNumIterationsCall(
CodeGenFunction &CGF, const OMPExecutableDirective &D,
- llvm::Value *DeviceID,
llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
const OMPLoopDirective &D)>
SizeEmitter) {
@@ -10201,20 +10198,12 @@ void CGOpenMPRuntime::emitTargetNumIterationsCall(
if (!isOpenMPDistributeDirective(Kind) || !isOpenMPTeamsDirective(Kind))
TD = getNestedDistributeDirective(CGM.getContext(), D);
if (!TD)
- return;
+ return llvm::ConstantInt::get(CGF.Int64Ty, 0);
+
const auto *LD = cast<OMPLoopDirective>(TD);
- auto &&CodeGen = [LD, DeviceID, SizeEmitter, &D, this](CodeGenFunction &CGF,
- PrePostActionTy &) {
- if (llvm::Value *NumIterations = SizeEmitter(CGF, *LD)) {
- llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
- llvm::Value *Args[] = {RTLoc, DeviceID, NumIterations};
- CGF.EmitRuntimeCall(
- OMPBuilder.getOrCreateRuntimeFunction(
- CGM.getModule(), OMPRTL___kmpc_push_target_tripcount_mapper),
- Args);
- }
- };
- emitInlinedDirective(CGF, OMPD_unknown, CodeGen);
+ if (llvm::Value *NumIterations = SizeEmitter(CGF, *LD))
+ return NumIterations;
+ return llvm::ConstantInt::get(CGF.Int64Ty, 0);
}
void CGOpenMPRuntime::emitTargetCall(
@@ -10308,26 +10297,34 @@ void CGOpenMPRuntime::emitTargetCall(
// Source location for the ident struct
llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
- // Emit tripcount for the target loop-based directive.
- emitTargetNumIterationsCall(CGF, D, DeviceID, SizeEmitter);
+ // Get tripcount for the target loop-based directive.
+ llvm::Value *NumIterations =
+ emitTargetNumIterationsCall(CGF, D, SizeEmitter);
+
+ // Arguments for the target kernel.
+ SmallVector<llvm::Value *> KernelArgs{
+ CGF.Builder.getInt32(/* Version */ 1),
+ PointerNum,
+ InputInfo.BasePointersArray.getPointer(),
+ InputInfo.PointersArray.getPointer(),
+ InputInfo.SizesArray.getPointer(),
+ MapTypesArray,
+ MapNamesArray,
+ InputInfo.MappersArray.getPointer(),
+ NumIterations};
+
+ // Arguments passed to the 'nowait' variant.
+ SmallVector<llvm::Value *> NoWaitKernelArgs{
+ CGF.Builder.getInt32(0),
+ llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
+ CGF.Builder.getInt32(0),
+ llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
+ };
+
+ bool HasNoWait = D.hasClausesOfKind<OMPNowaitClause>();
- bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
// The target region is an outlined function launched by the runtime
- // via calls __tgt_target() or __tgt_target_teams().
- //
- // __tgt_target() launches a target region with one team and one thread,
- // executing a serial region. This master thread may in turn launch
- // more threads within its team upon encountering a parallel region,
- // however, no additional teams can be launched on the device.
- //
- // __tgt_target_teams() launches a target region with one or more teams,
- // each with one or more threads. This call is required for target
- // constructs such as:
- // 'target teams'
- // 'target' / 'teams'
- // 'target teams distribute parallel for'
- // 'target parallel'
- // and so on.
+ // via calls to __tgt_target_kernel().
//
// Note that on the host and CPU targets, the runtime implementation of
// these calls simply call the outlined function without forking threads.
@@ -10338,70 +10335,15 @@ void CGOpenMPRuntime::emitTargetCall(
// In contrast, on the NVPTX target, the implementation of
// __tgt_target_teams() launches a GPU kernel with the requested number
// of teams and threads so no additional calls to the runtime are required.
- if (NumTeams) {
- // If we have NumTeams defined this means that we have an enclosed teams
- // region. Therefore we also expect to have NumThreads defined. These two
- // values should be defined in the presence of a teams directive,
- // regardless of having any clauses associated. If the user is using teams
- // but no clauses, these two values will be the default that should be
- // passed to the runtime library - a 32-bit integer with the value zero.
- assert(NumThreads && "Thread limit expression should be available along "
- "with number of teams.");
- SmallVector<llvm::Value *> OffloadingArgs = {
- RTLoc,
- DeviceID,
- OutlinedFnID,
- PointerNum,
- InputInfo.BasePointersArray.getPointer(),
- InputInfo.PointersArray.getPointer(),
- InputInfo.SizesArray.getPointer(),
- MapTypesArray,
- MapNamesArray,
- InputInfo.MappersArray.getPointer(),
- NumTeams,
- NumThreads};
- if (HasNowait) {
- // Add int32_t depNum = 0, void *depList = nullptr, int32_t
- // noAliasDepNum = 0, void *noAliasDepList = nullptr.
- OffloadingArgs.push_back(CGF.Builder.getInt32(0));
- OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
- OffloadingArgs.push_back(CGF.Builder.getInt32(0));
- OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
- }
- Return = CGF.EmitRuntimeCall(
- OMPBuilder.getOrCreateRuntimeFunction(
- CGM.getModule(), HasNowait
- ? OMPRTL___tgt_target_teams_nowait_mapper
- : OMPRTL___tgt_target_teams_mapper),
- OffloadingArgs);
- } else {
- SmallVector<llvm::Value *> OffloadingArgs = {
- RTLoc,
- DeviceID,
- OutlinedFnID,
- PointerNum,
- InputInfo.BasePointersArray.getPointer(),
- InputInfo.PointersArray.getPointer(),
- InputInfo.SizesArray.getPointer(),
- MapTypesArray,
- MapNamesArray,
- InputInfo.MappersArray.getPointer()};
- if (HasNowait) {
- // Add int32_t depNum = 0, void *depList = nullptr, int32_t
- // noAliasDepNum = 0, void *noAliasDepList = nullptr.
- OffloadingArgs.push_back(CGF.Builder.getInt32(0));
- OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
- OffloadingArgs.push_back(CGF.Builder.getInt32(0));
- OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
- }
- Return = CGF.EmitRuntimeCall(
- OMPBuilder.getOrCreateRuntimeFunction(
- CGM.getModule(), HasNowait ? OMPRTL___tgt_target_nowait_mapper
- : OMPRTL___tgt_target_mapper),
- OffloadingArgs);
- }
-
// Check the error code and execute the host version if required.
+ CGF.Builder.restoreIP(
+ HasNoWait ? OMPBuilder.emitTargetKernel(
+ CGF.Builder, Return, RTLoc, DeviceID, NumTeams,
+ NumThreads, OutlinedFnID, KernelArgs, NoWaitKernelArgs)
+ : OMPBuilder.emitTargetKernel(CGF.Builder, Return, RTLoc,
+ DeviceID, NumTeams, NumThreads,
+ OutlinedFnID, KernelArgs));
+
llvm::BasicBlock *OffloadFailedBlock =
CGF.createBasicBlock("omp_offload.failed");
llvm::BasicBlock *OffloadContBlock =
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index 7fc6a7e278e5..b95aef68335e 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -884,13 +884,11 @@ private:
llvm::Function *TaskFunction, QualType SharedsTy,
Address Shareds, const OMPTaskDataTy &Data);
- /// Emit code that pushes the trip count of loops associated with constructs
- /// 'target teams distribute' and 'teams distribute parallel for'.
- /// \param SizeEmitter Emits the int64 value for the number of iterations of
- /// the associated loop.
- void emitTargetNumIterationsCall(
+ /// Return the trip count of loops associated with constructs / 'target teams
+ /// distribute' and 'teams distribute parallel for'. \param SizeEmitter Emits
+ /// the int64 value for the number of iterations of the associated loop.
+ llvm::Value *emitTargetNumIterationsCall(
CodeGenFunction &CGF, const OMPExecutableDirective &D,
- llvm::Value *DeviceID,
llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
const OMPLoopDirective &D)>
SizeEmitter);
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 301f5278df69..db0b2ffd3a4f 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -2591,11 +2591,12 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
}
}
-static bool isSupportedByOpenMPIRBuilder(const OMPExecutableDirective &S) {
+static bool isSupportedByOpenMPIRBuilder(const OMPSimdDirective &S) {
// Check for unsupported clauses
- if (!S.clauses().empty()) {
- // Currently no clause is supported
- return false;
+ for (OMPClause *C : S.clauses()) {
+ // Currently only simdlen clause is supported
+ if (!isa<OMPSimdlenClause>(C))
+ return false;
}
// Check if we have a statement with the ordered directive.
@@ -2630,7 +2631,6 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
// Use the OpenMPIRBuilder if enabled.
if (UseOMPIRBuilder) {
// Emit the associated statement and get its loop representation.
- llvm::DebugLoc DL = SourceLocToDebugLoc(S.getBeginLoc());
const Stmt *Inner = S.getRawStmt();
llvm::CanonicalLoopInfo *CLI =
EmitOMPCollapsedCanonicalLoopNest(Inner, 1);
@@ -2638,7 +2638,15 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
llvm::OpenMPIRBuilder &OMPBuilder =
CGM.getOpenMPRuntime().getOMPBuilder();
// Add SIMD specific metadata
- OMPBuilder.applySimd(DL, CLI);
+ llvm::ConstantInt *Simdlen = nullptr;
+ if (const auto *C = S.getSingleClause<OMPSimdlenClause>()) {
+ RValue Len =
+ this->EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
+ /*ignoreResult=*/true);
+ auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
+ Simdlen = Val;
+ }
+ OMPBuilder.applySimd(CLI, Simdlen);
return;
}
};
@@ -5998,18 +6006,26 @@ static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
RMWOp = llvm::AtomicRMWInst::Xor;
break;
case BO_LT:
- RMWOp = X.getType()->hasSignedIntegerRepresentation()
- ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
- : llvm::AtomicRMWInst::Max)
- : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
- : llvm::AtomicRMWInst::UMax);
+ if (IsInteger)
+ RMWOp = X.getType()->hasSignedIntegerRepresentation()
+ ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
+ : llvm::AtomicRMWInst::Max)
+ : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
+ : llvm::AtomicRMWInst::UMax);
+ else
+ RMWOp = IsXLHSInRHSPart ? llvm::AtomicRMWInst::FMin
+ : llvm::AtomicRMWInst::FMax;
break;
case BO_GT:
- RMWOp = X.getType()->hasSignedIntegerRepresentation()
- ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
- : llvm::AtomicRMWInst::Min)
- : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
- : llvm::AtomicRMWInst::UMin);
+ if (IsInteger)
+ RMWOp = X.getType()->hasSignedIntegerRepresentation()
+ ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
+ : llvm::AtomicRMWInst::Min)
+ : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
+ : llvm::AtomicRMWInst::UMin);
+ else
+ RMWOp = IsXLHSInRHSPart ? llvm::AtomicRMWInst::FMax
+ : llvm::AtomicRMWInst::FMin;
break;
case BO_Assign:
RMWOp = llvm::AtomicRMWInst::Xchg;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 05942f462dd1..17c1c91c7e8f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -898,6 +898,20 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (D && D->hasAttr<NoProfileFunctionAttr>())
Fn->addFnAttr(llvm::Attribute::NoProfile);
+ if (D) {
+ // Function attributes take precedence over command line flags.
+ if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) {
+ switch (A->getThunkType()) {
+ case FunctionReturnThunksAttr::Kind::Keep:
+ break;
+ case FunctionReturnThunksAttr::Kind::Extern:
+ Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
+ break;
+ }
+ } else if (CGM.getCodeGenOpts().FunctionReturnThunks)
+ Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
+ }
+
if (FD && (getLangOpts().OpenCL ||
(getLangOpts().HIP && getLangOpts().CUDAIsDevice))) {
// Add metadata for a kernel function.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 56ed59d1e3f1..c372bab1eccb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -445,6 +445,7 @@ void CodeGenModule::checkAliases() {
void CodeGenModule::clear() {
DeferredDeclsToEmit.clear();
+ EmittedDeferredDecls.clear();
if (OpenMPRuntime)
OpenMPRuntime->clear();
}
@@ -510,6 +511,9 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
void CodeGenModule::Release() {
EmitDeferred();
+ DeferredDecls.insert(EmittedDeferredDecls.begin(),
+ EmittedDeferredDecls.end());
+ EmittedDeferredDecls.clear();
EmitVTablesOpportunistically();
applyGlobalValReplacements();
applyReplacements();
@@ -900,6 +904,9 @@ void CodeGenModule::Release() {
if (!getCodeGenOpts().StackProtectorGuardReg.empty())
getModule().setStackProtectorGuardReg(
getCodeGenOpts().StackProtectorGuardReg);
+ if (!getCodeGenOpts().StackProtectorGuardSymbol.empty())
+ getModule().setStackProtectorGuardSymbol(
+ getCodeGenOpts().StackProtectorGuardSymbol);
if (getCodeGenOpts().StackProtectorGuardOffset != INT_MAX)
getModule().setStackProtectorGuardOffset(
getCodeGenOpts().StackProtectorGuardOffset);
@@ -4286,6 +4293,9 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
getCUDARuntime().handleVarRegistration(D, *GV);
}
+ if (D)
+ SanitizerMD->reportGlobal(GV, *D);
+
LangAS ExpectedAS =
D ? D->getType().getAddressSpace()
: (LangOpts.OpenCL ? LangAS::opencl_global : LangAS::Default);
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index da43b9616c88..10b49da27dab 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -344,6 +344,20 @@ private:
std::vector<GlobalDecl> DeferredDeclsToEmit;
void addDeferredDeclToEmit(GlobalDecl GD) {
DeferredDeclsToEmit.emplace_back(GD);
+ addEmittedDeferredDecl(GD);
+ }
+
+ /// Decls that were DeferredDecls and have now been emitted.
+ llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls;
+
+ void addEmittedDeferredDecl(GlobalDecl GD) {
+ if (!llvm::isa<FunctionDecl>(GD.getDecl()))
+ return;
+ llvm::GlobalVariable::LinkageTypes L = getFunctionLinkage(GD);
+ if (llvm::GlobalValue::isLinkOnceLinkage(L) ||
+ llvm::GlobalValue::isWeakLinkage(L)) {
+ EmittedDeferredDecls[getMangledName(GD)] = GD;
+ }
}
/// List of alias we have emitted. Used to make sure that what they point to
@@ -1516,6 +1530,11 @@ public:
NewBuilder->WeakRefReferences = std::move(WeakRefReferences);
NewBuilder->TBAA = std::move(TBAA);
+
+ assert(NewBuilder->EmittedDeferredDecls.empty() &&
+ "Still have (unmerged) EmittedDeferredDecls deferred decls");
+
+ NewBuilder->EmittedDeferredDecls = std::move(EmittedDeferredDecls);
}
private:
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 95763d8e18b7..0cb63fbbe9e5 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -335,7 +335,42 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
if (auto *TTy = dyn_cast<RecordType>(Ty)) {
const RecordDecl *RD = TTy->getDecl()->getDefinition();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields;
+ using TBAAStructField = llvm::MDBuilder::TBAAStructField;
+ SmallVector<TBAAStructField, 4> Fields;
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ // Handle C++ base classes. Non-virtual bases can treated a a kind of
+ // field. Virtual bases are more complex and omitted, but avoid an
+ // incomplete view for NewStructPathTBAA.
+ if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
+ return BaseTypeMetadataCache[Ty] = nullptr;
+ for (const CXXBaseSpecifier &B : CXXRD->bases()) {
+ if (B.isVirtual())
+ continue;
+ QualType BaseQTy = B.getType();
+ const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl();
+ if (BaseRD->isEmpty())
+ continue;
+ llvm::MDNode *TypeNode = isValidBaseType(BaseQTy)
+ ? getBaseTypeInfo(BaseQTy)
+ : getTypeInfo(BaseQTy);
+ if (!TypeNode)
+ return BaseTypeMetadataCache[Ty] = nullptr;
+ uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
+ uint64_t Size =
+ Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
+ Fields.push_back(
+ llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
+ }
+ // The order in which base class subobjects are allocated is unspecified,
+ // so may differ from declaration order. In particular, Itanium ABI will
+ // allocate a primary base first.
+ // Since we exclude empty subobjects, the objects are not overlapping and
+ // their offsets are unique.
+ llvm::sort(Fields,
+ [](const TBAAStructField &A, const TBAAStructField &B) {
+ return A.Offset < B.Offset;
+ });
+ }
for (FieldDecl *Field : RD->fields()) {
if (Field->isZeroSize(Context) || Field->isUnnamedBitfield())
continue;
diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp
index 5f4eb9be981f..7848cf012633 100644
--- a/clang/lib/CodeGen/SanitizerMetadata.cpp
+++ b/clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -60,17 +60,17 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
Meta.NoHWAddress |= CGM.isInNoSanitizeList(
FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty);
- Meta.NoMemtag |= NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag);
- Meta.NoMemtag |= CGM.isInNoSanitizeList(
+ Meta.Memtag |=
+ static_cast<bool>(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals);
+ Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag);
+ Meta.Memtag &= !CGM.isInNoSanitizeList(
FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty);
- if (FsanitizeArgument.has(SanitizerKind::Address)) {
- // TODO(hctim): Make this conditional when we migrate off llvm.asan.globals.
- IsDynInit &= !CGM.isInNoSanitizeList(SanitizerKind::Address |
- SanitizerKind::KernelAddress,
- GV, Loc, Ty, "init");
- Meta.IsDynInit = IsDynInit;
- }
+ Meta.IsDynInit = IsDynInit && !Meta.NoAddress &&
+ FsanitizeArgument.has(SanitizerKind::Address) &&
+ !CGM.isInNoSanitizeList(SanitizerKind::Address |
+ SanitizerKind::KernelAddress,
+ GV, Loc, Ty, "init");
GV->setSanitizerMetadata(Meta);
}