summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
committerMichael Kruse <llvm-project@meinersbur.de>2025-01-03 10:22:51 +0100
commit38500d63e14ce340236840f60d356cdefb56a52c (patch)
tree17edbec446ce9b50d2f215a483b83afb293a635d /clang/lib/CodeGen
parent1a3d5daaef7a6a63448a497da3eff7fc9e23df26 (diff)
parent27f30029741ecf023baece7b3dde1ff9011ffefc (diff)
Merge branch 'main' into users/meinersbur/flang_runtime_split-headersusers/meinersbur/flang_runtime_split-headers
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp49
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp41
-rw-r--r--clang/lib/CodeGen/CGCall.cpp35
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp37
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp4
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp35
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp7
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.cpp17
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.h7
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp384
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h9
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp21
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h42
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenTBAA.cpp6
-rw-r--r--clang/lib/CodeGen/ConstantInitBuilder.cpp12
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp24
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp1
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp2
-rw-r--r--clang/lib/CodeGen/SanitizerMetadata.cpp78
-rw-r--r--clang/lib/CodeGen/Targets/AArch64.cpp68
-rw-r--r--clang/lib/CodeGen/Targets/RISCV.cpp8
23 files changed, 398 insertions, 500 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index bf9b04f02e9f..04358cd6d7c2 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -77,6 +77,7 @@
#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
+#include "llvm/Transforms/Instrumentation/TypeSanitizer.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar/EarlyCSE.h"
#include "llvm/Transforms/Scalar/GVN.h"
@@ -735,9 +736,17 @@ static void addSanitizers(const Triple &TargetTriple,
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
}
+ if (LangOpts.Sanitize.has(SanitizerKind::Type)) {
+ MPM.addPass(ModuleTypeSanitizerPass());
+ MPM.addPass(createModuleToFunctionPassAdaptor(TypeSanitizerPass()));
+ }
+
if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability))
MPM.addPass(NumericalStabilitySanitizerPass());
+ if (LangOpts.Sanitize.has(SanitizerKind::Realtime))
+ MPM.addPass(RealtimeSanitizerPass());
+
auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
if (LangOpts.Sanitize.has(Mask)) {
bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
@@ -789,13 +798,12 @@ static void addSanitizers(const Triple &TargetTriple,
}
if (LowerAllowCheckPass::IsRequested()) {
- // We can optimize after inliner, and PGO profile matching. The hook below
- // is called at the end `buildFunctionSimplificationPipeline`, which called
- // from `buildInlinerPipeline`, which called after profile matching.
- PB.registerScalarOptimizerLateEPCallback(
- [](FunctionPassManager &FPM, OptimizationLevel Level) {
- FPM.addPass(LowerAllowCheckPass());
- });
+ // We want to call it after inline, which is about OptimizerEarlyEPCallback.
+ PB.registerOptimizerEarlyEPCallback([](ModulePassManager &MPM,
+ OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase) {
+ MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass()));
+ });
}
}
@@ -1020,15 +1028,24 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
// of the pipeline.
if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
PB.registerScalarOptimizerLateEPCallback(
- [](FunctionPassManager &FPM, OptimizationLevel Level) {
- FPM.addPass(BoundsCheckingPass());
- });
-
- if (LangOpts.Sanitize.has(SanitizerKind::Realtime))
- PB.registerScalarOptimizerLateEPCallback(
- [](FunctionPassManager &FPM, OptimizationLevel Level) {
- RealtimeSanitizerOptions Opts;
- FPM.addPass(RealtimeSanitizerPass(Opts));
+ [this](FunctionPassManager &FPM, OptimizationLevel Level) {
+ BoundsCheckingPass::ReportingMode Mode;
+ bool Merge = CodeGenOpts.SanitizeMergeHandlers.has(
+ SanitizerKind::LocalBounds);
+
+ if (CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
+ Mode = BoundsCheckingPass::ReportingMode::Trap;
+ } else if (CodeGenOpts.SanitizeMinimalRuntime) {
+ Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds)
+ ? BoundsCheckingPass::ReportingMode::MinRuntime
+ : BoundsCheckingPass::ReportingMode::MinRuntimeAbort;
+ } else {
+ Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds)
+ ? BoundsCheckingPass::ReportingMode::FullRuntime
+ : BoundsCheckingPass::ReportingMode::FullRuntimeAbort;
+ }
+ BoundsCheckingPass::BoundsCheckingOptions Options(Mode, Merge);
+ FPM.addPass(BoundsCheckingPass(Options));
});
// Don't add sanitizers if we are here from ThinLTO PostLink. That already
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 497a0b3952af..4d4b7428abd5 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4860,6 +4860,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// Buffer is a void**.
Address Buf = EmitPointerWithAlignment(E->getArg(0));
+ if (getTarget().getTriple().getArch() == llvm::Triple::systemz) {
+ // On this target, the back end fills in the context buffer completely.
+ // It doesn't really matter if the frontend stores to the buffer before
+ // calling setjmp, the back-end is going to overwrite them anyway.
+ Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
+ return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
+ }
+
// Store the frame pointer to the setjmp buffer.
Value *FrameAddr = Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy),
@@ -10201,6 +10209,8 @@ CodeGenFunction::getSVEType(const SVETypeFlags &TypeFlags) {
case SVETypeFlags::EltTyInt64:
return llvm::ScalableVectorType::get(Builder.getInt64Ty(), 2);
+ case SVETypeFlags::EltTyMFloat8:
+ return llvm::ScalableVectorType::get(Builder.getInt8Ty(), 16);
case SVETypeFlags::EltTyFloat16:
return llvm::ScalableVectorType::get(Builder.getHalfTy(), 8);
case SVETypeFlags::EltTyBFloat16:
@@ -10646,7 +10656,7 @@ Value *CodeGenFunction::EmitSMELd1St1(const SVETypeFlags &TypeFlags,
NewOps.push_back(Ops[2]);
llvm::Value *BasePtr = Ops[3];
-
+ llvm::Value *RealSlice = Ops[1];
// If the intrinsic contains the vnum parameter, multiply it with the vector
// size in bytes.
if (Ops.size() == 5) {
@@ -10658,10 +10668,13 @@ Value *CodeGenFunction::EmitSMELd1St1(const SVETypeFlags &TypeFlags,
Builder.CreateMul(StreamingVectorLengthCall, Ops[4], "mulvl");
// The type of the ptr parameter is void *, so use Int8Ty here.
BasePtr = Builder.CreateGEP(Int8Ty, Ops[3], Mulvl);
+ RealSlice = Builder.CreateZExt(RealSlice, Int64Ty);
+ RealSlice = Builder.CreateAdd(RealSlice, Ops[4]);
+ RealSlice = Builder.CreateTrunc(RealSlice, Int32Ty);
}
NewOps.push_back(BasePtr);
NewOps.push_back(Ops[0]);
- NewOps.push_back(Ops[1]);
+ NewOps.push_back(RealSlice);
Function *F = CGM.getIntrinsic(IntID);
return Builder.CreateCall(F, NewOps);
}
@@ -10706,7 +10719,16 @@ Value *CodeGenFunction::EmitSVEDupX(Value *Scalar, llvm::Type *Ty) {
cast<llvm::VectorType>(Ty)->getElementCount(), Scalar);
}
-Value *CodeGenFunction::EmitSVEDupX(Value* Scalar) {
+Value *CodeGenFunction::EmitSVEDupX(Value *Scalar) {
+ if (auto *Ty = Scalar->getType(); Ty->isVectorTy()) {
+#ifndef NDEBUG
+ auto *VecTy = cast<llvm::VectorType>(Ty);
+ ElementCount EC = VecTy->getElementCount();
+ assert(EC.isScalar() && VecTy->getElementType() == Int8Ty &&
+ "Only <1 x i8> expected");
+#endif
+ Scalar = Builder.CreateExtractElement(Scalar, uint64_t(0));
+ }
return EmitSVEDupX(Scalar, getSVEVectorForElementType(Scalar->getType()));
}
@@ -11252,6 +11274,10 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
BuiltinID == SME::BI__builtin_sme_svstr_za)
return EmitSMELdrStr(TypeFlags, Ops, Builtin->LLVMIntrinsic);
+ // Emit set FPMR for intrinsics that require it
+ if (TypeFlags.setsFPMR())
+ Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_set_fpmr),
+ Ops.pop_back_val());
// Handle builtins which require their multi-vector operands to be swapped
swapCommutativeSMEOperands(BuiltinID, Ops);
@@ -19410,6 +19436,15 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: {
/*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(),
ArrayRef<Value *>{Op0, Op1}, nullptr, "hlsl.step");
}
+ case Builtin::BI__builtin_hlsl_wave_active_all_true: {
+ Value *Op = EmitScalarExpr(E->getArg(0));
+ assert(Op->getType()->isIntegerTy(1) &&
+ "Intrinsic WaveActiveAllTrue operand must be a bool");
+
+ Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic();
+ return EmitRuntimeCall(
+ Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), {Op});
+ }
case Builtin::BI__builtin_hlsl_wave_active_any_true: {
Value *Op = EmitScalarExpr(E->getArg(0));
assert(Op->getType()->isIntegerTy(1) &&
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7c8d962fa5a9..f139c30f3dfd 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3235,22 +3235,6 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::StructType *STy =
dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
- if (ArgI.isDirect() && !ArgI.getCanBeFlattened() && STy &&
- STy->getNumElements() > 1) {
- [[maybe_unused]] llvm::TypeSize StructSize =
- CGM.getDataLayout().getTypeAllocSize(STy);
- [[maybe_unused]] llvm::TypeSize PtrElementSize =
- CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(Ty));
- if (STy->containsHomogeneousScalableVectorTypes()) {
- assert(StructSize == PtrElementSize &&
- "Only allow non-fractional movement of structure with"
- "homogeneous scalable vector type");
-
- ArgVals.push_back(ParamValue::forDirect(AI));
- break;
- }
- }
-
Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg),
Arg->getName());
@@ -4379,7 +4363,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
llvm::PHINode *phiToUse = CGF.Builder.CreatePHI(valueToUse->getType(), 2,
"icr.to-use");
phiToUse->addIncoming(valueToUse, copyBB);
- phiToUse->addIncoming(llvm::UndefValue::get(valueToUse->getType()),
+ phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()),
originBB);
valueToUse = phiToUse;
}
@@ -4529,7 +4513,7 @@ void CodeGenFunction::EmitCallArgs(
ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
MD->param_type_end());
} else {
- const auto *FPT = Prototype.P.get<const FunctionProtoType *>();
+ const auto *FPT = cast<const FunctionProtoType *>(Prototype.P);
IsVariadic = FPT->isVariadic();
ExplicitCC = FPT->getExtInfo().getCC();
ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
@@ -5414,21 +5398,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::StructType *STy =
dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType());
- if (STy && ArgInfo.isDirect() && !ArgInfo.getCanBeFlattened()) {
- llvm::Type *SrcTy = ConvertTypeForMem(I->Ty);
- [[maybe_unused]] llvm::TypeSize SrcTypeSize =
- CGM.getDataLayout().getTypeAllocSize(SrcTy);
- [[maybe_unused]] llvm::TypeSize DstTypeSize =
- CGM.getDataLayout().getTypeAllocSize(STy);
- if (STy->containsHomogeneousScalableVectorTypes()) {
- assert(SrcTypeSize == DstTypeSize &&
- "Only allow non-fractional movement of structure with "
- "homogeneous scalable vector type");
-
- IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
- break;
- }
- }
// FIXME: Avoid the conversion through memory if possible.
Address Src = Address::invalid();
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 60f32f76109e..f29ddece5dbc 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2021,28 +2021,10 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
// ThisPtr may be null if the member function has an explicit 'this'
// parameter.
if (!ThisPtr.isNull()) {
- const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
- if (isa<ClassTemplateSpecializationDecl>(RD)) {
- // Create pointer type directly in this case.
- const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
- uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
- auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
- llvm::DIType *PointeeType =
- getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
- llvm::DIType *ThisPtrType =
- DBuilder.createPointerType(PointeeType, Size, Align);
- TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
- // TODO: This and the artificial type below are misleading, the
- // types aren't artificial the argument is, but the current
- // metadata doesn't represent that.
- ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
- Elts.push_back(ThisPtrType);
- } else {
- llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
- TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
- ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
- Elts.push_back(ThisPtrType);
- }
+ llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
+ TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
+ ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
+ Elts.push_back(ThisPtrType);
}
// Copy rest of the arguments.
@@ -2995,20 +2977,21 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
if (!ID)
return nullptr;
+ auto RuntimeLang =
+ static_cast<llvm::dwarf::SourceLanguage>(TheCU->getSourceLanguage());
+
// Return a forward declaration if this type was imported from a clang module,
// and this is not the compile unit with the implementation of the type (which
// may contain hidden ivars).
if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition() &&
!ID->getImplementation())
- return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
- ID->getName(),
- getDeclContextDescriptor(ID), Unit, 0);
+ return DBuilder.createForwardDecl(
+ llvm::dwarf::DW_TAG_structure_type, ID->getName(),
+ getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
// Get overall information about the record type for the debug info.
llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());
unsigned Line = getLineNumber(ID->getLocation());
- auto RuntimeLang =
- static_cast<llvm::dwarf::SourceLanguage>(TheCU->getSourceLanguage());
// If this is just a forward declaration return a special forward-declaration
// debug type since we won't be able to lay out the entire type.
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 2c3054605ee7..96517511b211 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -479,6 +479,10 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
!isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc))
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
+ if (getLangOpts().Sanitize.has(SanitizerKind::Type) &&
+ !isInNoSanitizeList(SanitizerKind::Type, Fn, Loc))
+ Fn->addFnAttr(llvm::Attribute::SanitizeType);
+
if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
!isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc))
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5fccc9cbb37e..ba1cba291553 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -52,11 +52,6 @@
using namespace clang;
using namespace CodeGen;
-// Experiment to make sanitizers easier to debug
-static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization(
- "ubsan-unique-traps", llvm::cl::Optional,
- llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check."));
-
// TODO: Introduce frontend options to enabled per sanitizers, similar to
// `fsanitize-trap`.
static llvm::cl::opt<bool> ClSanitizeGuardChecks(
@@ -1172,7 +1167,7 @@ llvm::Value *CodeGenFunction::GetCountedByFieldExprGEP(
Indices.push_back(Builder.getInt32(0));
return Builder.CreateInBoundsGEP(
ConvertType(QualType(RD->getTypeForDecl(), 0)), Res,
- RecIndicesTy(llvm::reverse(Indices)), "..counted_by.gep");
+ RecIndicesTy(llvm::reverse(Indices)), "counted_by.gep");
}
/// This method is typically called in contexts where we can't generate
@@ -1187,7 +1182,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfCountedByField(
const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) {
if (llvm::Value *GEP = GetCountedByFieldExprGEP(Base, FAMDecl, CountDecl))
return Builder.CreateAlignedLoad(ConvertType(CountDecl->getType()), GEP,
- getIntAlign(), "..counted_by.load");
+ getIntAlign(), "counted_by.load");
return nullptr;
}
@@ -3546,7 +3541,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
ArrayRef<llvm::Value *> FnArgs,
SanitizerHandler CheckHandler,
CheckRecoverableKind RecoverKind, bool IsFatal,
- llvm::BasicBlock *ContBB) {
+ llvm::BasicBlock *ContBB, bool NoMerge) {
assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
std::optional<ApplyDebugLocation> DL;
if (!CGF.Builder.getCurrentDebugLocation()) {
@@ -3581,6 +3576,10 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
llvm::AttributeList::FunctionIndex, B),
/*Local=*/true);
llvm::CallInst *HandlerCall = CGF.EmitNounwindRuntimeCall(Fn, FnArgs);
+ NoMerge = NoMerge || !CGF.CGM.getCodeGenOpts().OptimizationLevel ||
+ (CGF.CurCodeDecl && CGF.CurCodeDecl->hasAttr<OptimizeNoneAttr>());
+ if (NoMerge)
+ HandlerCall->addFnAttr(llvm::Attribute::NoMerge);
if (!MayReturn) {
HandlerCall->setDoesNotReturn();
CGF.Builder.CreateUnreachable();
@@ -3602,6 +3601,7 @@ void CodeGenFunction::EmitCheck(
llvm::Value *FatalCond = nullptr;
llvm::Value *RecoverableCond = nullptr;
llvm::Value *TrapCond = nullptr;
+ bool NoMerge = false;
for (int i = 0, n = Checked.size(); i < n; ++i) {
llvm::Value *Check = Checked[i].first;
// -fsanitize-trap= overrides -fsanitize-recover=.
@@ -3612,6 +3612,9 @@ void CodeGenFunction::EmitCheck(
? RecoverableCond
: FatalCond;
Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check;
+
+ if (!CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Checked[i].second))
+ NoMerge = true;
}
if (ClSanitizeGuardChecks) {
@@ -3626,7 +3629,7 @@ void CodeGenFunction::EmitCheck(
}
if (TrapCond)
- EmitTrapCheck(TrapCond, CheckHandler);
+ EmitTrapCheck(TrapCond, CheckHandler, NoMerge);
if (!FatalCond && !RecoverableCond)
return;
@@ -3692,7 +3695,7 @@ void CodeGenFunction::EmitCheck(
// Simple case: we need to generate a single handler call, either
// fatal, or non-fatal.
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind,
- (FatalCond != nullptr), Cont);
+ (FatalCond != nullptr), Cont, NoMerge);
} else {
// Emit two handler calls: first one for set of unrecoverable checks,
// another one for recoverable.
@@ -3702,10 +3705,10 @@ void CodeGenFunction::EmitCheck(
Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
EmitBlock(FatalHandlerBB);
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, true,
- NonFatalHandlerBB);
+ NonFatalHandlerBB, NoMerge);
EmitBlock(NonFatalHandlerBB);
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, false,
- Cont);
+ Cont, NoMerge);
}
EmitBlock(Cont);
@@ -3895,7 +3898,8 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
}
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
- SanitizerHandler CheckHandlerID) {
+ SanitizerHandler CheckHandlerID,
+ bool NoMerge) {
llvm::BasicBlock *Cont = createBasicBlock("cont");
// If we're optimizing, collapse all calls to trap down to just one per
@@ -3905,9 +3909,8 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
- bool NoMerge = ClSanitizeDebugDeoptimization ||
- !CGM.getCodeGenOpts().OptimizationLevel ||
- (CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
+ NoMerge = NoMerge || !CGM.getCodeGenOpts().OptimizationLevel ||
+ (CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
if (TrapBB && !NoMerge) {
auto Call = TrapBB->begin();
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 4ae8a2b22b1b..4b71bd730ce1 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2102,7 +2102,8 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
Expr *InitVector = E->getInit(0);
// Initialize from another scalable vector of the same type.
- if (InitVector->getType() == E->getType())
+ if (InitVector->getType().getCanonicalType() ==
+ E->getType().getCanonicalType())
return Visit(InitVector);
}
@@ -2369,10 +2370,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
ScalableDstTy->getElementCount().getKnownMinValue() / 8);
}
if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
- llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
+ llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
llvm::Value *Result = Builder.CreateInsertVector(
- ScalableDstTy, UndefVec, Src, Zero, "cast.scalable");
+ ScalableDstTy, PoisonVec, Src, Zero, "cast.scalable");
if (Result->getType() != DstTy)
Result = Builder.CreateBitCast(Result, DstTy);
return Result;
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 2c293523fca8..c354e58e15f4 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -389,6 +389,11 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
CGM.getIntrinsic(getThreadIdIntrinsic());
return buildVectorInput(B, ThreadIDIntrinsic, Ty);
}
+ if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) {
+ llvm::Function *GroupThreadIDIntrinsic =
+ CGM.getIntrinsic(getGroupThreadIdIntrinsic());
+ return buildVectorInput(B, GroupThreadIDIntrinsic, Ty);
+ }
if (D.hasAttr<HLSLSV_GroupIDAttr>()) {
llvm::Function *GroupIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_group_id);
return buildVectorInput(B, GroupIDIntrinsic, Ty);
@@ -507,13 +512,17 @@ void CGHLSLRuntime::generateGlobalCtorDtorCalls() {
IP = Token->getNextNode();
}
IRBuilder<> B(IP);
- for (auto *Fn : CtorFns)
- B.CreateCall(FunctionCallee(Fn), {}, OB);
+ for (auto *Fn : CtorFns) {
+ auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
+ CI->setCallingConv(Fn->getCallingConv());
+ }
// Insert global dtors before the terminator of the last instruction
B.SetInsertPoint(F.back().getTerminator());
- for (auto *Fn : DtorFns)
- B.CreateCall(FunctionCallee(Fn), {}, OB);
+ for (auto *Fn : DtorFns) {
+ auto CI = B.CreateCall(FunctionCallee(Fn), {}, OB);
+ CI->setCallingConv(Fn->getCallingConv());
+ }
}
// No need to keep global ctors/dtors for non-lib profile after call to
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index bb120c8b5e9e..edb87f9d5efd 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -86,11 +86,13 @@ public:
GENERATE_HLSL_INTRINSIC_FUNCTION(Step, step)
GENERATE_HLSL_INTRINSIC_FUNCTION(Radians, radians)
GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(GroupThreadId, thread_id_in_group)
GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot)
GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot)
GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddI8Packed, dot4add_i8packed)
GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddU8Packed, dot4add_u8packed)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAllTrue, wave_all)
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any)
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits)
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
@@ -101,8 +103,9 @@ public:
GENERATE_HLSL_INTRINSIC_FUNCTION(SClamp, sclamp)
GENERATE_HLSL_INTRINSIC_FUNCTION(UClamp, uclamp)
- GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, handle_fromBinding)
- GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, bufferUpdateCounter)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding,
+ resource_handlefrombinding)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter)
GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync,
group_memory_barrier_with_group_sync)
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 6a5860242035..30c3834de139 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -4085,7 +4085,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy,
CGF.Builder.CreateConstGEP(DependenciesArray, *P), KmpDependInfoTy);
} else {
assert(E && "Expected a non-null expression");
- LValue &PosLVal = *Pos.get<LValue *>();
+ LValue &PosLVal = *cast<LValue *>(Pos);
llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc());
Base = CGF.MakeAddrLValue(
CGF.Builder.CreateGEP(CGF, DependenciesArray, Idx), KmpDependInfoTy);
@@ -4113,7 +4113,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy,
if (unsigned *P = Pos.dyn_cast<unsigned *>()) {
++(*P);
} else {
- LValue &PosLVal = *Pos.get<LValue *>();
+ LValue &PosLVal = *cast<LValue *>(Pos);
llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc());
Idx = CGF.Builder.CreateNUWAdd(Idx,
llvm::ConstantInt::get(Idx->getType(), 1));
@@ -7770,7 +7770,7 @@ private:
if (const auto *Base = Data.dyn_cast<const CXXRecordDecl *>())
getPlainLayout(Base, Layout, /*AsBase=*/true);
else
- Layout.push_back(Data.get<const FieldDecl *>());
+ Layout.push_back(cast<const FieldDecl *>(Data));
}
}
@@ -8333,9 +8333,9 @@ public:
MapCombinedInfoTy &CombinedInfo, llvm::OpenMPIRBuilder &OMPBuilder,
const llvm::DenseSet<CanonicalDeclPtr<const Decl>> &SkipVarSet =
llvm::DenseSet<CanonicalDeclPtr<const Decl>>()) const {
- assert(CurDir.is<const OMPExecutableDirective *>() &&
+ assert(isa<const OMPExecutableDirective *>(CurDir) &&
"Expect a executable directive");
- const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
+ const auto *CurExecDir = cast<const OMPExecutableDirective *>(CurDir);
generateAllInfoForClauses(CurExecDir->clauses(), CombinedInfo, OMPBuilder,
SkipVarSet);
}
@@ -8345,9 +8345,9 @@ public:
/// in \a CombinedInfo).
void generateAllInfoForMapper(MapCombinedInfoTy &CombinedInfo,
llvm::OpenMPIRBuilder &OMPBuilder) const {
- assert(CurDir.is<const OMPDeclareMapperDecl *>() &&
+ assert(isa<const OMPDeclareMapperDecl *>(CurDir) &&
"Expect a declare mapper directive");
- const auto *CurMapperDir = CurDir.get<const OMPDeclareMapperDecl *>();
+ const auto *CurMapperDir = cast<const OMPDeclareMapperDecl *>(CurDir);
generateAllInfoForClauses(CurMapperDir->clauses(), CombinedInfo,
OMPBuilder);
}
@@ -8519,9 +8519,9 @@ public:
DeclComponentLists.emplace_back(MCL, OMPC_MAP_tofrom, Unknown,
/*IsImpicit = */ true, nullptr,
nullptr);
- assert(CurDir.is<const OMPExecutableDirective *>() &&
+ assert(isa<const OMPExecutableDirective *>(CurDir) &&
"Expect a executable directive");
- const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
+ const auto *CurExecDir = cast<const OMPExecutableDirective *>(CurDir);
bool HasMapBasePtr = false;
bool HasMapArraySec = false;
for (const auto *C : CurExecDir->getClausesOfKind<OMPMapClause>()) {
@@ -9042,337 +9042,69 @@ void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D,
return;
ASTContext &C = CGM.getContext();
QualType Ty = D->getType();
- QualType PtrTy = C.getPointerType(Ty).withRestrict();
- QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
auto *MapperVarDecl =
cast<VarDecl>(cast<DeclRefExpr>(D->getMapperVarRef())->getDecl());
- SourceLocation Loc = D->getLocation();
CharUnits ElementSize = C.getTypeSizeInChars(Ty);
llvm::Type *ElemTy = CGM.getTypes().ConvertTypeForMem(Ty);
- // Prepare mapper function arguments and attributes.
- ImplicitParamDecl HandleArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
- C.VoidPtrTy, ImplicitParamKind::Other);
- ImplicitParamDecl BaseArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
- ImplicitParamKind::Other);
- ImplicitParamDecl BeginArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
- C.VoidPtrTy, ImplicitParamKind::Other);
- ImplicitParamDecl SizeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
- ImplicitParamKind::Other);
- ImplicitParamDecl TypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
- ImplicitParamKind::Other);
- ImplicitParamDecl NameArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
- ImplicitParamKind::Other);
- FunctionArgList Args;
- Args.push_back(&HandleArg);
- Args.push_back(&BaseArg);
- Args.push_back(&BeginArg);
- Args.push_back(&SizeArg);
- Args.push_back(&TypeArg);
- Args.push_back(&NameArg);
- const CGFunctionInfo &FnInfo =
- CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
- llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
+ CodeGenFunction MapperCGF(CGM);
+ MappableExprsHandler::MapCombinedInfoTy CombinedInfo;
+ auto PrivatizeAndGenMapInfoCB =
+ [&](llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP, llvm::Value *PtrPHI,
+ llvm::Value *BeginArg) -> llvm::OpenMPIRBuilder::MapInfosTy & {
+ MapperCGF.Builder.restoreIP(CodeGenIP);
+
+ // Privatize the declared variable of mapper to be the current array
+ // element.
+ Address PtrCurrent(
+ PtrPHI, ElemTy,
+ Address(BeginArg, MapperCGF.VoidPtrTy, CGM.getPointerAlign())
+ .getAlignment()
+ .alignmentOfArrayElement(ElementSize));
+ CodeGenFunction::OMPPrivateScope Scope(MapperCGF);
+ Scope.addPrivate(MapperVarDecl, PtrCurrent);
+ (void)Scope.Privatize();
+
+ // Get map clause information.
+ MappableExprsHandler MEHandler(*D, MapperCGF);
+ MEHandler.generateAllInfoForMapper(CombinedInfo, OMPBuilder);
+
+ auto FillInfoMap = [&](MappableExprsHandler::MappingExprInfo &MapExpr) {
+ return emitMappingInformation(MapperCGF, OMPBuilder, MapExpr);
+ };
+ if (CGM.getCodeGenOpts().getDebugInfo() !=
+ llvm::codegenoptions::NoDebugInfo) {
+ CombinedInfo.Names.resize(CombinedInfo.Exprs.size());
+ llvm::transform(CombinedInfo.Exprs, CombinedInfo.Names.begin(),
+ FillInfoMap);
+ }
+
+ return CombinedInfo;
+ };
+
+ auto CustomMapperCB = [&](unsigned I, llvm::Function **MapperFunc) {
+ if (CombinedInfo.Mappers[I]) {
+ // Call the corresponding mapper function.
+ *MapperFunc = getOrCreateUserDefinedMapperFunc(
+ cast<OMPDeclareMapperDecl>(CombinedInfo.Mappers[I]));
+ assert(*MapperFunc && "Expect a valid mapper function is available.");
+ return true;
+ }
+ return false;
+ };
+
SmallString<64> TyStr;
llvm::raw_svector_ostream Out(TyStr);
CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out);
std::string Name = getName({"omp_mapper", TyStr, D->getName()});
- auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
- Name, &CGM.getModule());
- CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
- Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
- // Start the mapper function code generation.
- CodeGenFunction MapperCGF(CGM);
- MapperCGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
- // Compute the starting and end addresses of array elements.
- llvm::Value *Size = MapperCGF.EmitLoadOfScalar(
- MapperCGF.GetAddrOfLocalVar(&SizeArg), /*Volatile=*/false,
- C.getPointerType(Int64Ty), Loc);
- // Prepare common arguments for array initiation and deletion.
- llvm::Value *Handle = MapperCGF.EmitLoadOfScalar(
- MapperCGF.GetAddrOfLocalVar(&HandleArg),
- /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
- llvm::Value *BaseIn = MapperCGF.EmitLoadOfScalar(
- MapperCGF.GetAddrOfLocalVar(&BaseArg),
- /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
- llvm::Value *BeginIn = MapperCGF.EmitLoadOfScalar(
- MapperCGF.GetAddrOfLocalVar(&BeginArg),
- /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
- // Convert the size in bytes into the number of array elements.
- Size = MapperCGF.Builder.CreateExactUDiv(
- Size, MapperCGF.Builder.getInt64(ElementSize.getQuantity()));
- llvm::Value *PtrBegin = MapperCGF.Builder.CreateBitCast(
- BeginIn, CGM.getTypes().ConvertTypeForMem(PtrTy));
- llvm::Value *PtrEnd = MapperCGF.Builder.CreateGEP(ElemTy, PtrBegin, Size);
- llvm::Value *MapType = MapperCGF.EmitLoadOfScalar(
- MapperCGF.GetAddrOfLocalVar(&TypeArg), /*Volatile=*/false,
- C.getPointerType(Int64Ty), Loc);
- llvm::Value *MapName = MapperCGF.EmitLoadOfScalar(
- MapperCGF.GetAddrOfLocalVar(&NameArg),
- /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
-
- // Emit array initiation if this is an array section and \p MapType indicates
- // that memory allocation is required.
- llvm::BasicBlock *HeadBB = MapperCGF.createBasicBlock("omp.arraymap.head");
- emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
- MapName, ElementSize, HeadBB, /*IsInit=*/true);
-
- // Emit a for loop to iterate through SizeArg of elements and map all of them.
-
- // Emit the loop header block.
- MapperCGF.EmitBlock(HeadBB);
- llvm::BasicBlock *BodyBB = MapperCGF.createBasicBlock("omp.arraymap.body");
- llvm::BasicBlock *DoneBB = MapperCGF.createBasicBlock("omp.done");
- // Evaluate whether the initial condition is satisfied.
- llvm::Value *IsEmpty =
- MapperCGF.Builder.CreateICmpEQ(PtrBegin, PtrEnd, "omp.arraymap.isempty");
- MapperCGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
- llvm::BasicBlock *EntryBB = MapperCGF.Builder.GetInsertBlock();
-
- // Emit the loop body block.
- MapperCGF.EmitBlock(BodyBB);
- llvm::BasicBlock *LastBB = BodyBB;
- llvm::PHINode *PtrPHI = MapperCGF.Builder.CreatePHI(
- PtrBegin->getType(), 2, "omp.arraymap.ptrcurrent");
- PtrPHI->addIncoming(PtrBegin, EntryBB);
- Address PtrCurrent(PtrPHI, ElemTy,
- MapperCGF.GetAddrOfLocalVar(&BeginArg)
- .getAlignment()
- .alignmentOfArrayElement(ElementSize));
- // Privatize the declared variable of mapper to be the current array element.
- CodeGenFunction::OMPPrivateScope Scope(MapperCGF);
- Scope.addPrivate(MapperVarDecl, PtrCurrent);
- (void)Scope.Privatize();
- // Get map clause information. Fill up the arrays with all mapped variables.
- MappableExprsHandler::MapCombinedInfoTy Info;
- MappableExprsHandler MEHandler(*D, MapperCGF);
- MEHandler.generateAllInfoForMapper(Info, OMPBuilder);
-
- // Call the runtime API __tgt_mapper_num_components to get the number of
- // pre-existing components.
- llvm::Value *OffloadingArgs[] = {Handle};
- llvm::Value *PreviousSize = MapperCGF.EmitRuntimeCall(
- OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
- OMPRTL___tgt_mapper_num_components),
- OffloadingArgs);
- llvm::Value *ShiftedPreviousSize = MapperCGF.Builder.CreateShl(
- PreviousSize,
- MapperCGF.Builder.getInt64(MappableExprsHandler::getFlagMemberOffset()));
-
- // Fill up the runtime mapper handle for all components.
- for (unsigned I = 0; I < Info.BasePointers.size(); ++I) {
- llvm::Value *CurBaseArg = MapperCGF.Builder.CreateBitCast(
- Info.BasePointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
- llvm::Value *CurBeginArg = MapperCGF.Builder.CreateBitCast(
- Info.Pointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
- llvm::Value *CurSizeArg = Info.Sizes[I];
- llvm::Value *CurNameArg =
- (CGM.getCodeGenOpts().getDebugInfo() ==
- llvm::codegenoptions::NoDebugInfo)
- ? llvm::ConstantPointerNull::get(CGM.VoidPtrTy)
- : emitMappingInformation(MapperCGF, OMPBuilder, Info.Exprs[I]);
-
- // Extract the MEMBER_OF field from the map type.
- llvm::Value *OriMapType = MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- Info.Types[I]));
- llvm::Value *MemberMapType =
- MapperCGF.Builder.CreateNUWAdd(OriMapType, ShiftedPreviousSize);
-
- // Combine the map type inherited from user-defined mapper with that
- // specified in the program. According to the OMP_MAP_TO and OMP_MAP_FROM
- // bits of the \a MapType, which is the input argument of the mapper
- // function, the following code will set the OMP_MAP_TO and OMP_MAP_FROM
- // bits of MemberMapType.
- // [OpenMP 5.0], 1.2.6. map-type decay.
- // | alloc | to | from | tofrom | release | delete
- // ----------------------------------------------------------
- // alloc | alloc | alloc | alloc | alloc | release | delete
- // to | alloc | to | alloc | to | release | delete
- // from | alloc | alloc | from | from | release | delete
- // tofrom | alloc | to | from | tofrom | release | delete
- llvm::Value *LeftToFrom = MapperCGF.Builder.CreateAnd(
- MapType,
- MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_TO |
- OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
- llvm::BasicBlock *AllocBB = MapperCGF.createBasicBlock("omp.type.alloc");
- llvm::BasicBlock *AllocElseBB =
- MapperCGF.createBasicBlock("omp.type.alloc.else");
- llvm::BasicBlock *ToBB = MapperCGF.createBasicBlock("omp.type.to");
- llvm::BasicBlock *ToElseBB = MapperCGF.createBasicBlock("omp.type.to.else");
- llvm::BasicBlock *FromBB = MapperCGF.createBasicBlock("omp.type.from");
- llvm::BasicBlock *EndBB = MapperCGF.createBasicBlock("omp.type.end");
- llvm::Value *IsAlloc = MapperCGF.Builder.CreateIsNull(LeftToFrom);
- MapperCGF.Builder.CreateCondBr(IsAlloc, AllocBB, AllocElseBB);
- // In case of alloc, clear OMP_MAP_TO and OMP_MAP_FROM.
- MapperCGF.EmitBlock(AllocBB);
- llvm::Value *AllocMapType = MapperCGF.Builder.CreateAnd(
- MemberMapType,
- MapperCGF.Builder.getInt64(
- ~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_TO |
- OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
- MapperCGF.Builder.CreateBr(EndBB);
- MapperCGF.EmitBlock(AllocElseBB);
- llvm::Value *IsTo = MapperCGF.Builder.CreateICmpEQ(
- LeftToFrom,
- MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_TO)));
- MapperCGF.Builder.CreateCondBr(IsTo, ToBB, ToElseBB);
- // In case of to, clear OMP_MAP_FROM.
- MapperCGF.EmitBlock(ToBB);
- llvm::Value *ToMapType = MapperCGF.Builder.CreateAnd(
- MemberMapType,
- MapperCGF.Builder.getInt64(
- ~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
- MapperCGF.Builder.CreateBr(EndBB);
- MapperCGF.EmitBlock(ToElseBB);
- llvm::Value *IsFrom = MapperCGF.Builder.CreateICmpEQ(
- LeftToFrom,
- MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
- MapperCGF.Builder.CreateCondBr(IsFrom, FromBB, EndBB);
- // In case of from, clear OMP_MAP_TO.
- MapperCGF.EmitBlock(FromBB);
- llvm::Value *FromMapType = MapperCGF.Builder.CreateAnd(
- MemberMapType,
- MapperCGF.Builder.getInt64(
- ~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_TO)));
- // In case of tofrom, do nothing.
- MapperCGF.EmitBlock(EndBB);
- LastBB = EndBB;
- llvm::PHINode *CurMapType =
- MapperCGF.Builder.CreatePHI(CGM.Int64Ty, 4, "omp.maptype");
- CurMapType->addIncoming(AllocMapType, AllocBB);
- CurMapType->addIncoming(ToMapType, ToBB);
- CurMapType->addIncoming(FromMapType, FromBB);
- CurMapType->addIncoming(MemberMapType, ToElseBB);
-
- llvm::Value *OffloadingArgs[] = {Handle, CurBaseArg, CurBeginArg,
- CurSizeArg, CurMapType, CurNameArg};
- if (Info.Mappers[I]) {
- // Call the corresponding mapper function.
- llvm::Function *MapperFunc = getOrCreateUserDefinedMapperFunc(
- cast<OMPDeclareMapperDecl>(Info.Mappers[I]));
- assert(MapperFunc && "Expect a valid mapper function is available.");
- MapperCGF.EmitNounwindRuntimeCall(MapperFunc, OffloadingArgs);
- } else {
- // Call the runtime API __tgt_push_mapper_component to fill up the runtime
- // data structure.
- MapperCGF.EmitRuntimeCall(
- OMPBuilder.getOrCreateRuntimeFunction(
- CGM.getModule(), OMPRTL___tgt_push_mapper_component),
- OffloadingArgs);
- }
- }
-
- // Update the pointer to point to the next element that needs to be mapped,
- // and check whether we have mapped all elements.
- llvm::Value *PtrNext = MapperCGF.Builder.CreateConstGEP1_32(
- ElemTy, PtrPHI, /*Idx0=*/1, "omp.arraymap.next");
- PtrPHI->addIncoming(PtrNext, LastBB);
- llvm::Value *IsDone =
- MapperCGF.Builder.CreateICmpEQ(PtrNext, PtrEnd, "omp.arraymap.isdone");
- llvm::BasicBlock *ExitBB = MapperCGF.createBasicBlock("omp.arraymap.exit");
- MapperCGF.Builder.CreateCondBr(IsDone, ExitBB, BodyBB);
-
- MapperCGF.EmitBlock(ExitBB);
- // Emit array deletion if this is an array section and \p MapType indicates
- // that deletion is required.
- emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
- MapName, ElementSize, DoneBB, /*IsInit=*/false);
-
- // Emit the function exit block.
- MapperCGF.EmitBlock(DoneBB, /*IsFinished=*/true);
- MapperCGF.FinishFunction();
- UDMMap.try_emplace(D, Fn);
+ auto *NewFn = OMPBuilder.emitUserDefinedMapper(PrivatizeAndGenMapInfoCB,
+ ElemTy, Name, CustomMapperCB);
+ UDMMap.try_emplace(D, NewFn);
if (CGF)
FunctionUDMMap[CGF->CurFn].push_back(D);
}
-/// Emit the array initialization or deletion portion for user-defined mapper
-/// code generation. First, it evaluates whether an array section is mapped and
-/// whether the \a MapType instructs to delete this section. If \a IsInit is
-/// true, and \a MapType indicates to not delete this array, array
-/// initialization code is generated. If \a IsInit is false, and \a MapType
-/// indicates to not this array, array deletion code is generated.
-void CGOpenMPRuntime::emitUDMapperArrayInitOrDel(
- CodeGenFunction &MapperCGF, llvm::Value *Handle, llvm::Value *Base,
- llvm::Value *Begin, llvm::Value *Size, llvm::Value *MapType,
- llvm::Value *MapName, CharUnits ElementSize, llvm::BasicBlock *ExitBB,
- bool IsInit) {
- StringRef Prefix = IsInit ? ".init" : ".del";
-
- // Evaluate if this is an array section.
- llvm::BasicBlock *BodyBB =
- MapperCGF.createBasicBlock(getName({"omp.array", Prefix}));
- llvm::Value *IsArray = MapperCGF.Builder.CreateICmpSGT(
- Size, MapperCGF.Builder.getInt64(1), "omp.arrayinit.isarray");
- llvm::Value *DeleteBit = MapperCGF.Builder.CreateAnd(
- MapType,
- MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_DELETE)));
- llvm::Value *DeleteCond;
- llvm::Value *Cond;
- if (IsInit) {
- // base != begin?
- llvm::Value *BaseIsBegin = MapperCGF.Builder.CreateICmpNE(Base, Begin);
- // IsPtrAndObj?
- llvm::Value *PtrAndObjBit = MapperCGF.Builder.CreateAnd(
- MapType,
- MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_PTR_AND_OBJ)));
- PtrAndObjBit = MapperCGF.Builder.CreateIsNotNull(PtrAndObjBit);
- BaseIsBegin = MapperCGF.Builder.CreateAnd(BaseIsBegin, PtrAndObjBit);
- Cond = MapperCGF.Builder.CreateOr(IsArray, BaseIsBegin);
- DeleteCond = MapperCGF.Builder.CreateIsNull(
- DeleteBit, getName({"omp.array", Prefix, ".delete"}));
- } else {
- Cond = IsArray;
- DeleteCond = MapperCGF.Builder.CreateIsNotNull(
- DeleteBit, getName({"omp.array", Prefix, ".delete"}));
- }
- Cond = MapperCGF.Builder.CreateAnd(Cond, DeleteCond);
- MapperCGF.Builder.CreateCondBr(Cond, BodyBB, ExitBB);
-
- MapperCGF.EmitBlock(BodyBB);
- // Get the array size by multiplying element size and element number (i.e., \p
- // Size).
- llvm::Value *ArraySize = MapperCGF.Builder.CreateNUWMul(
- Size, MapperCGF.Builder.getInt64(ElementSize.getQuantity()));
- // Remove OMP_MAP_TO and OMP_MAP_FROM from the map type, so that it achieves
- // memory allocation/deletion purpose only.
- llvm::Value *MapTypeArg = MapperCGF.Builder.CreateAnd(
- MapType,
- MapperCGF.Builder.getInt64(
- ~static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_TO |
- OpenMPOffloadMappingFlags::OMP_MAP_FROM)));
- MapTypeArg = MapperCGF.Builder.CreateOr(
- MapTypeArg,
- MapperCGF.Builder.getInt64(
- static_cast<std::underlying_type_t<OpenMPOffloadMappingFlags>>(
- OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT)));
-
- // Call the runtime API __tgt_push_mapper_component to fill up the runtime
- // data structure.
- llvm::Value *OffloadingArgs[] = {Handle, Base, Begin,
- ArraySize, MapTypeArg, MapName};
- MapperCGF.EmitRuntimeCall(
- OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
- OMPRTL___tgt_push_mapper_component),
- OffloadingArgs);
-}
-
llvm::Function *CGOpenMPRuntime::getOrCreateUserDefinedMapperFunc(
const OMPDeclareMapperDecl *D) {
auto I = UDMMap.find(D);
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index 56d502d92806..8ab5ee70a19f 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -559,15 +559,6 @@ protected:
llvm::Value *Ctor, llvm::Value *CopyCtor,
llvm::Value *Dtor, SourceLocation Loc);
- /// Emit the array initialization or deletion portion for user-defined mapper
- /// code generation.
- void emitUDMapperArrayInitOrDel(CodeGenFunction &MapperCGF,
- llvm::Value *Handle, llvm::Value *BasePtr,
- llvm::Value *Ptr, llvm::Value *Size,
- llvm::Value *MapType, llvm::Value *MapName,
- CharUnits ElementSize,
- llvm::BasicBlock *ExitBB, bool IsInit);
-
struct TaskResultTy {
llvm::Value *NewTask = nullptr;
llvm::Function *TaskEntry = nullptr;
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 698baf853507..3974739d2abb 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -458,6 +458,27 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
case Stmt::OpenACCCombinedConstructClass:
EmitOpenACCCombinedConstruct(cast<OpenACCCombinedConstruct>(*S));
break;
+ case Stmt::OpenACCDataConstructClass:
+ EmitOpenACCDataConstruct(cast<OpenACCDataConstruct>(*S));
+ break;
+ case Stmt::OpenACCEnterDataConstructClass:
+ EmitOpenACCEnterDataConstruct(cast<OpenACCEnterDataConstruct>(*S));
+ break;
+ case Stmt::OpenACCExitDataConstructClass:
+ EmitOpenACCExitDataConstruct(cast<OpenACCExitDataConstruct>(*S));
+ break;
+ case Stmt::OpenACCHostDataConstructClass:
+ EmitOpenACCHostDataConstruct(cast<OpenACCHostDataConstruct>(*S));
+ break;
+ case Stmt::OpenACCWaitConstructClass:
+ EmitOpenACCWaitConstruct(cast<OpenACCWaitConstruct>(*S));
+ break;
+ case Stmt::OpenACCInitConstructClass:
+ EmitOpenACCInitConstruct(cast<OpenACCInitConstruct>(*S));
+ break;
+ case Stmt::OpenACCShutdownConstructClass:
+ EmitOpenACCShutdownConstruct(cast<OpenACCShutdownConstruct>(*S));
+ break;
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 2bc10cdd2d34..af58fa64f865 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -837,6 +837,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
if (SanOpts.has(SanitizerKind::Thread))
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+ if (SanOpts.has(SanitizerKind::Type))
+ Fn->addFnAttr(llvm::Attribute::SanitizeType);
if (SanOpts.has(SanitizerKind::NumericalStability))
Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index eaea0d8a08ac..1a5c42f8f974 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4094,6 +4094,45 @@ public:
EmitStmt(S.getLoop());
}
+ void EmitOpenACCDataConstruct(const OpenACCDataConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // simply emitting its structured block, but in the future we will implement
+ // some sort of IR.
+ EmitStmt(S.getStructuredBlock());
+ }
+
+ void EmitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
+ void EmitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
+ void EmitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // simply emitting its structured block, but in the future we will implement
+ // some sort of IR.
+ EmitStmt(S.getStructuredBlock());
+ }
+
+ void EmitOpenACCWaitConstruct(const OpenACCWaitConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
+ void EmitOpenACCInitConstruct(const OpenACCInitConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
+ void EmitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
//===--------------------------------------------------------------------===//
// LValue Expression Emission
//===--------------------------------------------------------------------===//
@@ -5142,7 +5181,8 @@ public:
/// Create a basic block that will call the trap intrinsic, and emit a
/// conditional branch to it, for the -ftrapv checks.
- void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID);
+ void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID,
+ bool NoMerge = false);
/// Emit a call to trap or debugtrap and attach function attribute
/// "trap-func-name" if specified.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d3d5c0743a52..c49f76314882 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -397,8 +397,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
if (LangOpts.HLSL)
createHLSLRuntime();
- // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
- if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
+ // Enable TBAA unless it's suppressed. TSan and TySan need TBAA even at O0.
+ if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Thread | SanitizerKind::Type) ||
(!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts,
getLangOpts()));
@@ -1218,6 +1218,9 @@ void CodeGenModule::Release() {
getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1);
if (getTriple().isOSLinux()) {
+ if (LangOpts.PointerAuthCalls)
+ getModule().addModuleFlag(llvm::Module::Min, "ptrauth-sign-personality",
+ 1);
assert(getTriple().isOSBinFormatELF());
using namespace llvm::ELF;
uint64_t PAuthABIVersion =
@@ -4280,7 +4283,7 @@ void CodeGenModule::emitMultiVersionFunctions() {
getContext().forEachMultiversionedFunctionVersion(
FD, [&](const FunctionDecl *CurFD) {
llvm::SmallVector<StringRef, 8> Feats;
- bool IsDefined = CurFD->doesThisDeclarationHaveABody();
+ bool IsDefined = CurFD->getDefinition() != nullptr;
if (const auto *TA = CurFD->getAttr<TargetAttr>()) {
assert(getTarget().getTriple().isX86() && "Unsupported target");
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 6eed8e1d2b67..75e66bae79af 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -314,8 +314,10 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
}
llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
- // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
- if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
+ // At -O0 or relaxed aliasing, TBAA is not emitted for regular types (unless
+ // we're running TypeSanitizer).
+ if (!Features.Sanitize.has(SanitizerKind::Type) &&
+ (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing))
return nullptr;
// If the type has the may_alias attribute (even on a typedef), it is
diff --git a/clang/lib/CodeGen/ConstantInitBuilder.cpp b/clang/lib/CodeGen/ConstantInitBuilder.cpp
index 549d5dd66b12..ddbf3ef74337 100644
--- a/clang/lib/CodeGen/ConstantInitBuilder.cpp
+++ b/clang/lib/CodeGen/ConstantInitBuilder.cpp
@@ -20,10 +20,10 @@ using namespace CodeGen;
llvm::Type *ConstantInitFuture::getType() const {
assert(Data && "dereferencing null future");
- if (Data.is<llvm::Constant*>()) {
- return Data.get<llvm::Constant*>()->getType();
+ if (const auto *C = dyn_cast<llvm::Constant *>(Data)) {
+ return C->getType();
} else {
- return Data.get<ConstantInitBuilderBase*>()->Buffer[0]->getType();
+ return cast<ConstantInitBuilderBase *>(Data)->Buffer[0]->getType();
}
}
@@ -37,10 +37,10 @@ void ConstantInitFuture::abandon() {
void ConstantInitFuture::installInGlobal(llvm::GlobalVariable *GV) {
assert(Data && "installing null future");
- if (Data.is<llvm::Constant*>()) {
- GV->setInitializer(Data.get<llvm::Constant*>());
+ if (auto *C = dyn_cast<llvm::Constant *>(Data)) {
+ GV->setInitializer(C);
} else {
- auto &builder = *Data.get<ConstantInitBuilderBase*>();
+ auto &builder = *cast<ConstantInitBuilderBase *>(Data);
assert(builder.Buffer.size() == 1);
builder.setGlobalInitializer(GV, builder.Buffer[0]);
builder.Buffer.clear();
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 96c89b2728e5..cda218eac34a 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1146,12 +1146,15 @@ struct CounterCoverageMappingBuilder
/// Create a Branch Region around a SwitchCase for code coverage
/// and add it to the function's SourceRegions.
- void createSwitchCaseRegion(const SwitchCase *SC, Counter TrueCnt) {
+ /// Returns Counter that corresponds to SC.
+ Counter createSwitchCaseRegion(const SwitchCase *SC, Counter ParentCount) {
// Push region onto RegionStack but immediately pop it (which adds it to
// the function's SourceRegions) because it doesn't apply to any other
// source other than the SwitchCase.
+ Counter TrueCnt = getRegionCounter(SC);
popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(),
- Counter::getZero()));
+ subtractCounters(ParentCount, TrueCnt)));
+ return TrueCnt;
}
/// Check whether a region with bounds \c StartLoc and \c EndLoc
@@ -1863,16 +1866,22 @@ struct CounterCoverageMappingBuilder
const SwitchCase *Case = S->getSwitchCaseList();
for (; Case; Case = Case->getNextSwitchCase()) {
HasDefaultCase = HasDefaultCase || isa<DefaultStmt>(Case);
- auto CaseCount = getRegionCounter(Case);
+ auto CaseCount = createSwitchCaseRegion(Case, ParentCount);
CaseCountSum = addCounters(CaseCountSum, CaseCount, /*Simplify=*/false);
- createSwitchCaseRegion(Case, CaseCount);
}
// If no explicit default case exists, create a branch region to represent
// the hidden branch, which will be added later by the CodeGen. This region
// will be associated with the switch statement's condition.
if (!HasDefaultCase) {
- Counter DefaultCount = subtractCounters(ParentCount, CaseCountSum);
- createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount);
+ // Simplify is skipped while building the counters above: it can get
+ // really slow on top of switches with thousands of cases. Instead,
+ // trigger simplification by adding zero to the last counter.
+ CaseCountSum =
+ addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true);
+
+ // This is considered as the False count on SwitchStmt.
+ Counter SwitchFalse = subtractCounters(ParentCount, CaseCountSum);
+ createBranchRegion(S->getCond(), CaseCountSum, SwitchFalse);
}
}
@@ -2370,8 +2379,7 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
} else {
Ctx.dump(R.Count, OS);
- if (R.Kind == CounterMappingRegion::BranchRegion ||
- R.Kind == CounterMappingRegion::MCDCBranchRegion) {
+ if (R.isBranch()) {
OS << ", ";
Ctx.dump(R.FalseCount, OS);
}
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 8cbd09d02c75..cf9e338236e5 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3302,6 +3302,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
CharUnits Align = CGM.getContext().getDeclAlign(VD);
Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
}
+ Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
Builder.CreateRet(Val);
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d587daac5a88..90651c3bafe2 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -3454,7 +3454,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
if (inheritanceModelHasOnlyOneField(IsFunc, DstInheritance)) {
Dst = FirstField;
} else {
- Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
+ Dst = llvm::PoisonValue::get(ConvertMemberPointerType(DstTy));
unsigned Idx = 0;
Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
if (inheritanceModelHasNVOffsetField(IsFunc, DstInheritance))
diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp
index c1a6b223480a..61fdf3399ff3 100644
--- a/clang/lib/CodeGen/SanitizerMetadata.cpp
+++ b/clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -19,9 +19,10 @@ using namespace CodeGen;
SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
-static bool isAsanHwasanOrMemTag(const SanitizerSet &SS) {
+static bool isAsanHwasanMemTagOrTysan(const SanitizerSet &SS) {
return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress |
- SanitizerKind::HWAddress | SanitizerKind::MemTag);
+ SanitizerKind::HWAddress | SanitizerKind::MemTag |
+ SanitizerKind::Type);
}
static SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) {
@@ -31,13 +32,44 @@ static SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) {
return Mask;
}
+static bool shouldTagGlobal(const llvm::GlobalVariable &G) {
+ // For now, don't instrument constant data, as it'll be in .rodata anyway. It
+ // may be worth instrumenting these in future to stop them from being used as
+ // gadgets.
+ if (G.getName().starts_with("llvm.") || G.isThreadLocal() || G.isConstant())
+ return false;
+
+ // Globals can be placed implicitly or explicitly in sections. There's two
+ // different types of globals that meet this criteria that cause problems:
+ // 1. Function pointers that are going into various init arrays (either
+ // explicitly through `__attribute__((section(<foo>)))` or implicitly
+ // through `__attribute__((constructor)))`, such as ".(pre)init(_array)",
+ // ".fini(_array)", ".ctors", and ".dtors". These function pointers end up
+ // overaligned and overpadded, making iterating over them problematic, and
+ // each function pointer is individually tagged (so the iteration over
+ // them causes SIGSEGV/MTE[AS]ERR).
+ // 2. Global variables put into an explicit section, where the section's name
+ // is a valid C-style identifier. The linker emits a `__start_<name>` and
+ // `__stop_<name>` symbol for the section, so that you can iterate over
+ // globals within this section. Unfortunately, again, these globals would
+ // be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
+ //
+ // To mitigate both these cases, and because specifying a section is rare
+ // outside of these two cases, disable MTE protection for globals in any
+ // section.
+ if (G.hasSection())
+ return false;
+
+ return true;
+}
+
void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
SourceLocation Loc, StringRef Name,
QualType Ty,
SanitizerMask NoSanitizeAttrMask,
bool IsDynInit) {
SanitizerSet FsanitizeArgument = CGM.getLangOpts().Sanitize;
- if (!isAsanHwasanOrMemTag(FsanitizeArgument))
+ if (!isAsanHwasanMemTagOrTysan(FsanitizeArgument))
return;
FsanitizeArgument.Mask = expandKernelSanitizerMasks(FsanitizeArgument.Mask);
@@ -57,11 +89,15 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
Meta.NoHWAddress |= CGM.isInNoSanitizeList(
FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty);
- 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 (shouldTagGlobal(*GV)) {
+ 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);
+ } else {
+ Meta.Memtag = false;
+ }
Meta.IsDynInit = IsDynInit && !Meta.NoAddress &&
FsanitizeArgument.has(SanitizerKind::Address) &&
@@ -70,11 +106,32 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
GV, Loc, Ty, "init");
GV->setSanitizerMetadata(Meta);
+
+ if (Ty.isNull() || !CGM.getLangOpts().Sanitize.has(SanitizerKind::Type) ||
+ NoSanitizeAttrMask & SanitizerKind::Type)
+ return;
+
+ llvm::MDNode *TBAAInfo = CGM.getTBAATypeInfo(Ty);
+ if (!TBAAInfo || TBAAInfo == CGM.getTBAATypeInfo(CGM.getContext().CharTy))
+ return;
+
+ llvm::Metadata *GlobalMetadata[] = {llvm::ConstantAsMetadata::get(GV),
+ TBAAInfo};
+
+ // Metadata for the global already registered.
+ if (llvm::MDNode::getIfExists(CGM.getLLVMContext(), GlobalMetadata))
+ return;
+
+ llvm::MDNode *ThisGlobal =
+ llvm::MDNode::get(CGM.getLLVMContext(), GlobalMetadata);
+ llvm::NamedMDNode *TysanGlobals =
+ CGM.getModule().getOrInsertNamedMetadata("llvm.tysan.globals");
+ TysanGlobals->addOperand(ThisGlobal);
}
void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
bool IsDynInit) {
- if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
+ if (!isAsanHwasanMemTagOrTysan(CGM.getLangOpts().Sanitize))
return;
std::string QualName;
llvm::raw_string_ostream OS(QualName);
@@ -88,6 +145,9 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
for (auto *Attr : D.specific_attrs<NoSanitizeAttr>())
NoSanitizeMask |= Attr->getMask();
+ if (D.hasExternalStorage())
+ NoSanitizeMask |= SanitizerKind::Type;
+
return NoSanitizeMask;
};
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index be33e26f0478..0680b4828b6d 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -52,6 +52,7 @@ private:
bool isIllegalVectorType(QualType Ty) const;
+ bool passAsAggregateType(QualType Ty) const;
bool passAsPureScalableType(QualType Ty, unsigned &NV, unsigned &NP,
SmallVectorImpl<llvm::Type *> &CoerceToSeq) const;
@@ -337,6 +338,10 @@ ABIArgInfo AArch64ABIInfo::coerceAndExpandPureScalableAggregate(
NSRN += NVec;
NPRN += NPred;
+ // Handle SVE vector tuples.
+ if (Ty->isSVESizelessBuiltinType())
+ return ABIArgInfo::getDirect();
+
llvm::Type *UnpaddedCoerceToType =
UnpaddedCoerceToSeq.size() == 1
? UnpaddedCoerceToSeq[0]
@@ -362,7 +367,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
if (isIllegalVectorType(Ty))
return coerceIllegalVector(Ty, NSRN, NPRN);
- if (!isAggregateTypeForABI(Ty)) {
+ if (!passAsAggregateType(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
@@ -417,7 +422,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
// elsewhere for GNU compatibility.
uint64_t Size = getContext().getTypeSize(Ty);
bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
- if (IsEmpty || Size == 0) {
+ if (!Ty->isSVESizelessBuiltinType() && (IsEmpty || Size == 0)) {
if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
return ABIArgInfo::getIgnore();
@@ -504,7 +509,7 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128)
return getNaturalAlignIndirect(RetTy);
- if (!isAggregateTypeForABI(RetTy)) {
+ if (!passAsAggregateType(RetTy)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
RetTy = EnumTy->getDecl()->getIntegerType();
@@ -519,7 +524,8 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
}
uint64_t Size = getContext().getTypeSize(RetTy);
- if (isEmptyRecord(getContext(), RetTy, true) || Size == 0)
+ if (!RetTy->isSVESizelessBuiltinType() &&
+ (isEmptyRecord(getContext(), RetTy, true) || Size == 0))
return ABIArgInfo::getIgnore();
const Type *Base = nullptr;
@@ -654,6 +660,15 @@ bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
return true;
}
+bool AArch64ABIInfo::passAsAggregateType(QualType Ty) const {
+ if (Kind == AArch64ABIKind::AAPCS && Ty->isSVESizelessBuiltinType()) {
+ const auto *BT = Ty->castAs<BuiltinType>();
+ return !BT->isSVECount() &&
+ getContext().getBuiltinVectorTypeInfo(BT).NumVectors > 1;
+ }
+ return isAggregateTypeForABI(Ty);
+}
+
// Check if a type needs to be passed in registers as a Pure Scalable Type (as
// defined by AAPCS64). Return the number of data vectors and the number of
// predicate vectors in the type, into `NVec` and `NPred`, respectively. Upon
@@ -719,37 +734,38 @@ bool AArch64ABIInfo::passAsPureScalableType(
return true;
}
- const auto *VT = Ty->getAs<VectorType>();
- if (!VT)
- return false;
+ if (const auto *VT = Ty->getAs<VectorType>()) {
+ if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
+ ++NPred;
+ if (CoerceToSeq.size() + 1 > 12)
+ return false;
+ CoerceToSeq.push_back(convertFixedToScalableVectorType(VT));
+ return true;
+ }
- if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
- ++NPred;
- if (CoerceToSeq.size() + 1 > 12)
- return false;
- CoerceToSeq.push_back(convertFixedToScalableVectorType(VT));
- return true;
- }
+ if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
+ ++NVec;
+ if (CoerceToSeq.size() + 1 > 12)
+ return false;
+ CoerceToSeq.push_back(convertFixedToScalableVectorType(VT));
+ return true;
+ }
- if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
- ++NVec;
- if (CoerceToSeq.size() + 1 > 12)
- return false;
- CoerceToSeq.push_back(convertFixedToScalableVectorType(VT));
- return true;
+ return false;
}
- if (!VT->isBuiltinType())
+ if (!Ty->isBuiltinType())
return false;
- switch (cast<BuiltinType>(VT)->getKind()) {
+ bool isPredicate;
+ switch (Ty->getAs<BuiltinType>()->getKind()) {
#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
case BuiltinType::Id: \
- ++NVec; \
+ isPredicate = false; \
break;
#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
case BuiltinType::Id: \
- ++NPred; \
+ isPredicate = true; \
break;
#define SVE_TYPE(Name, Id, SingletonId)
#include "clang/Basic/AArch64SVEACLETypes.def"
@@ -761,6 +777,10 @@ bool AArch64ABIInfo::passAsPureScalableType(
getContext().getBuiltinVectorTypeInfo(cast<BuiltinType>(Ty));
assert(Info.NumVectors > 0 && Info.NumVectors <= 4 &&
"Expected 1, 2, 3 or 4 vectors!");
+ if (isPredicate)
+ NPred += Info.NumVectors;
+ else
+ NVec += Info.NumVectors;
auto VTy = llvm::ScalableVectorType::get(CGT.ConvertType(Info.ElementType),
Info.EC.getKnownMinValue());
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index b04e436c665f..873e696e1328 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -495,13 +495,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
}
- ABIArgInfo Info = ABIArgInfo::getDirect();
-
- // If it is tuple type, it can't be flattened.
- if (llvm::StructType *STy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty)))
- Info.setCanBeFlattened(!STy->containsHomogeneousScalableVectorTypes());
-
- return Info;
+ return ABIArgInfo::getDirect();
}
if (const VectorType *VT = Ty->getAs<VectorType>())