diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 363 |
1 files changed, 276 insertions, 87 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 98d59b7..65f5468 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -40,13 +40,13 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/CodeGen/BackendUtil.h" #include "clang/CodeGen/ConstantInitBuilder.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" @@ -61,16 +61,19 @@ #include "llvm/IR/ProfileSummary.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/ProfileData/SampleProf.h" +#include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/CRC.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Hash.h" #include "llvm/Support/TimeProfiler.h" -#include "llvm/Support/xxhash.h" +#include "llvm/TargetParser/AArch64TargetParser.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/Triple.h" #include "llvm/TargetParser/X86TargetParser.h" +#include "llvm/Transforms/Instrumentation/KCFI.h" #include "llvm/Transforms/Utils/BuildLibCalls.h" #include <optional> #include <set> @@ -222,7 +225,9 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { return createMSP430TargetCodeGenInfo(CGM); case llvm::Triple::riscv32: - case llvm::Triple::riscv64: { + case llvm::Triple::riscv64: + case llvm::Triple::riscv32be: + case llvm::Triple::riscv64be: { StringRef ABIStr = Target.getABI(); unsigned XLen = Target.getPointerWidth(LangAS::Default); unsigned ABIFLen = 0; @@ -377,15 +382,11 @@ static void checkDataLayoutConsistency(const TargetInfo &Target, Check("bfloat", llvm::Type::getBFloatTy(Context), Target.BFloat16Align); Check("float", llvm::Type::getFloatingPointTy(Context, *Target.FloatFormat), Target.FloatAlign); - // FIXME: AIX specifies wrong double alignment in DataLayout - if (!Triple.isOSAIX()) { - Check("double", - llvm::Type::getFloatingPointTy(Context, *Target.DoubleFormat), - Target.DoubleAlign); - Check("long double", - llvm::Type::getFloatingPointTy(Context, *Target.LongDoubleFormat), - Target.LongDoubleAlign); - } + Check("double", llvm::Type::getFloatingPointTy(Context, *Target.DoubleFormat), + Target.DoubleAlign); + Check("long double", + llvm::Type::getFloatingPointTy(Context, *Target.LongDoubleFormat), + Target.LongDoubleAlign); if (Target.hasFloat128Type()) Check("__float128", llvm::Type::getFP128Ty(Context), Target.Float128Align); if (Target.hasIbm128Type()) @@ -493,10 +494,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, CodeGenOpts.ProfileInstrumentUsePath, *FS, CodeGenOpts.ProfileRemappingFile); if (auto E = ReaderOrErr.takeError()) { - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "Error in reading profile %0: %1"); llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) { - Diags.Report(DiagID) + Diags.Report(diag::err_reading_profile) << CodeGenOpts.ProfileInstrumentUsePath << EI.message(); }); return; @@ -540,12 +539,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, this->MSHotPatchFunctions.push_back(std::string{*I}); } else { auto &DE = Context.getDiagnostics(); - unsigned DiagID = - DE.getCustomDiagID(DiagnosticsEngine::Error, - "failed to open hotpatch functions file " - "(-fms-hotpatch-functions-file): %0 : %1"); - DE.Report(DiagID) << CGO.MSSecureHotPatchFunctionsFile - << BufOrErr.getError().message(); + DE.Report(diag::err_open_hotpatch_file_failed) + << CGO.MSSecureHotPatchFunctionsFile + << BufOrErr.getError().message(); } } @@ -957,6 +953,22 @@ static bool isStackProtectorOn(const LangOptions &LangOpts, return LangOpts.getStackProtector() == Mode; } +std::optional<llvm::Attribute::AttrKind> +CodeGenModule::StackProtectorAttribute(const Decl *D) const { + if (D && D->hasAttr<NoStackProtectorAttr>()) + ; // Do nothing. + else if (D && D->hasAttr<StrictGuardStackCheckAttr>() && + isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPOn)) + return llvm::Attribute::StackProtectStrong; + else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPOn)) + return llvm::Attribute::StackProtect; + else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPStrong)) + return llvm::Attribute::StackProtectStrong; + else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq)) + return llvm::Attribute::StackProtectReq; + return std::nullopt; +} + void CodeGenModule::Release() { Module *Primary = getContext().getCurrentNamedModule(); if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule()) @@ -1129,11 +1141,15 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1); } if (CodeGenOpts.ControlFlowGuard) { - // Function ID tables and checks for Control Flow Guard (cfguard=2). - getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 2); + // Function ID tables and checks for Control Flow Guard. + getModule().addModuleFlag( + llvm::Module::Warning, "cfguard", + static_cast<unsigned>(llvm::ControlFlowGuardMode::Enabled)); } else if (CodeGenOpts.ControlFlowGuardNoChecks) { - // Function ID tables for Control Flow Guard (cfguard=1). - getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1); + // Function ID tables for Control Flow Guard. + getModule().addModuleFlag( + llvm::Module::Warning, "cfguard", + static_cast<unsigned>(llvm::ControlFlowGuardMode::TableOnly)); } if (CodeGenOpts.EHContGuard) { // Function ID tables for EH Continuation Guard. @@ -1272,6 +1288,12 @@ void CodeGenModule::Release() { CodeGenOpts.PatchableFunctionEntryOffset); if (CodeGenOpts.SanitizeKcfiArity) getModule().addModuleFlag(llvm::Module::Override, "kcfi-arity", 1); + // Store the hash algorithm choice for use in LLVM passes + getModule().addModuleFlag( + llvm::Module::Override, "kcfi-hash", + llvm::MDString::get( + getLLVMContext(), + llvm::stringifyKCFIHashAlgorithm(CodeGenOpts.SanitizeKcfiHash))); } if (CodeGenOpts.CFProtectionReturn && @@ -1394,6 +1416,36 @@ void CodeGenModule::Release() { } } } + if ((T.isARM() || T.isThumb()) && getTriple().isTargetAEABI() && + getTriple().isOSBinFormatELF()) { + uint32_t TagVal = 0; + llvm::Module::ModFlagBehavior DenormalTagBehavior = llvm::Module::Max; + if (getCodeGenOpts().FPDenormalMode == + llvm::DenormalMode::getPositiveZero()) { + TagVal = llvm::ARMBuildAttrs::PositiveZero; + } else if (getCodeGenOpts().FPDenormalMode == + llvm::DenormalMode::getIEEE()) { + TagVal = llvm::ARMBuildAttrs::IEEEDenormals; + DenormalTagBehavior = llvm::Module::Override; + } else if (getCodeGenOpts().FPDenormalMode == + llvm::DenormalMode::getPreserveSign()) { + TagVal = llvm::ARMBuildAttrs::PreserveFPSign; + } + getModule().addModuleFlag(DenormalTagBehavior, "arm-eabi-fp-denormal", + TagVal); + + if (getLangOpts().getDefaultExceptionMode() != + LangOptions::FPExceptionModeKind::FPE_Ignore) + getModule().addModuleFlag(llvm::Module::Min, "arm-eabi-fp-exceptions", + llvm::ARMBuildAttrs::Allowed); + + if (getLangOpts().NoHonorNaNs && getLangOpts().NoHonorInfs) + TagVal = llvm::ARMBuildAttrs::AllowIEEENormal; + else + TagVal = llvm::ARMBuildAttrs::AllowIEEE754; + getModule().addModuleFlag(llvm::Module::Min, "arm-eabi-fp-number-model", + TagVal); + } if (CodeGenOpts.StackClashProtector) getModule().addModuleFlag( @@ -1512,6 +1564,9 @@ void CodeGenModule::Release() { case CodeGenOptions::FramePointerKind::Reserved: getModule().setFramePointer(llvm::FramePointerKind::Reserved); break; + case CodeGenOptions::FramePointerKind::NonLeafNoReserve: + getModule().setFramePointer(llvm::FramePointerKind::NonLeafNoReserve); + break; case CodeGenOptions::FramePointerKind::NonLeaf: getModule().setFramePointer(llvm::FramePointerKind::NonLeaf); break; @@ -1576,16 +1631,39 @@ void CodeGenModule::Release() { setVisibilityFromDLLStorageClass(LangOpts, getModule()); // Check the tail call symbols are truly undefined. - if (getTriple().isPPC() && !MustTailCallUndefinedGlobals.empty()) { - for (auto &I : MustTailCallUndefinedGlobals) { - if (!I.first->isDefined()) - getDiags().Report(I.second, diag::err_ppc_impossible_musttail) << 2; - else { - StringRef MangledName = getMangledName(GlobalDecl(I.first)); - llvm::GlobalValue *Entry = GetGlobalValue(MangledName); - if (!Entry || Entry->isWeakForLinker() || - Entry->isDeclarationForLinker()) + if (!MustTailCallUndefinedGlobals.empty()) { + if (getTriple().isPPC()) { + for (auto &I : MustTailCallUndefinedGlobals) { + if (!I.first->isDefined()) getDiags().Report(I.second, diag::err_ppc_impossible_musttail) << 2; + else { + StringRef MangledName = getMangledName(GlobalDecl(I.first)); + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + if (!Entry || Entry->isWeakForLinker() || + Entry->isDeclarationForLinker()) + getDiags().Report(I.second, diag::err_ppc_impossible_musttail) << 2; + } + } + } else if (getTriple().isMIPS()) { + for (auto &I : MustTailCallUndefinedGlobals) { + const FunctionDecl *FD = I.first; + StringRef MangledName = getMangledName(GlobalDecl(FD)); + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + + if (!Entry) + continue; + + bool CalleeIsLocal; + if (Entry->isDeclarationForLinker()) { + // For declarations, only visibility can indicate locality. + CalleeIsLocal = + Entry->hasHiddenVisibility() || Entry->hasProtectedVisibility(); + } else { + CalleeIsLocal = Entry->isDSOLocal(); + } + + if (!CalleeIsLocal) + getDiags().Report(I.second, diag::err_mips_impossible_musttail) << 1; } } } @@ -1632,6 +1710,22 @@ void CodeGenModule::EmitBackendOptionsMetadata( getModule().addModuleFlag(llvm::Module::Min, "SmallDataLimit", CodeGenOpts.SmallDataLimit); } + + // Set AllocToken configuration for backend pipeline. + if (LangOpts.AllocTokenMode) { + StringRef S = llvm::getAllocTokenModeAsString(*LangOpts.AllocTokenMode); + getModule().addModuleFlag(llvm::Module::Error, "alloc-token-mode", + llvm::MDString::get(VMContext, S)); + } + if (LangOpts.AllocTokenMax) + getModule().addModuleFlag( + llvm::Module::Error, "alloc-token-max", + llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), + *LangOpts.AllocTokenMax)); + if (CodeGenOpts.SanitizeAllocTokenFastABI) + getModule().addModuleFlag(llvm::Module::Error, "alloc-token-fast-abi", 1); + if (CodeGenOpts.SanitizeAllocTokenExtended) + getModule().addModuleFlag(llvm::Module::Error, "alloc-token-extended", 1); } void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { @@ -1737,20 +1831,25 @@ void CodeGenModule::Error(SourceLocation loc, StringRef message) { /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified stmt yet. void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type) { - unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, - "cannot compile this %0 yet"); std::string Msg = Type; - getDiags().Report(Context.getFullLoc(S->getBeginLoc()), DiagID) + getDiags().Report(Context.getFullLoc(S->getBeginLoc()), + diag::err_codegen_unsupported) << Msg << S->getSourceRange(); } +void CodeGenModule::ErrorUnsupported(const Stmt *S, llvm::StringRef Type) { + getDiags().Report(Context.getFullLoc(S->getBeginLoc()), + diag::err_codegen_unsupported) + << Type << S->getSourceRange(); +} + /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified decl yet. void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type) { - unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, - "cannot compile this %0 yet"); std::string Msg = Type; - getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg; + getDiags().Report(Context.getFullLoc(D->getLocation()), + diag::err_codegen_unsupported) + << Msg; } void CodeGenModule::runWithSufficientStackSpace(SourceLocation Loc, @@ -2431,8 +2530,8 @@ llvm::ConstantInt *CodeGenModule::CreateKCFITypeId(QualType T, StringRef Salt) { if (getCodeGenOpts().SanitizeCfiICallGeneralizePointers) Out << ".generalized"; - return llvm::ConstantInt::get(Int32Ty, - static_cast<uint32_t>(llvm::xxHash64(OutName))); + return llvm::ConstantInt::get( + Int32Ty, llvm::getKCFITypeID(OutName, getCodeGenOpts().SanitizeKcfiHash)); } void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD, @@ -2709,17 +2808,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, if (!hasUnwindExceptions(LangOpts)) B.addAttribute(llvm::Attribute::NoUnwind); - if (D && D->hasAttr<NoStackProtectorAttr>()) - ; // Do nothing. - else if (D && D->hasAttr<StrictGuardStackCheckAttr>() && - isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPOn)) - B.addAttribute(llvm::Attribute::StackProtectStrong); - else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPOn)) - B.addAttribute(llvm::Attribute::StackProtect); - else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPStrong)) - B.addAttribute(llvm::Attribute::StackProtectStrong); - else if (isStackProtectorOn(LangOpts, getTriple(), LangOptions::SSPReq)) - B.addAttribute(llvm::Attribute::StackProtectReq); + if (std::optional<llvm::Attribute::AttrKind> Attr = + StackProtectorAttribute(D)) { + B.addAttribute(*Attr); + } if (!D) { // Non-entry HLSL functions must always be inlined. @@ -2906,6 +2998,24 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { addUsedOrCompilerUsedGlobal(GV); } +/// Get the feature delta from the default feature map for the given target CPU. +static std::vector<std::string> +getFeatureDeltaFromDefault(const CodeGenModule &CGM, StringRef TargetCPU, + llvm::StringMap<bool> &FeatureMap) { + llvm::StringMap<bool> DefaultFeatureMap; + CGM.getTarget().initFeatureMap( + DefaultFeatureMap, CGM.getContext().getDiagnostics(), TargetCPU, {}); + + std::vector<std::string> Delta; + for (const auto &[K, V] : FeatureMap) { + auto DefaultIt = DefaultFeatureMap.find(K); + if (DefaultIt == DefaultFeatureMap.end() || DefaultIt->getValue() != V) + Delta.push_back((V ? "+" : "-") + K.str()); + } + + return Delta; +} + bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, llvm::AttrBuilder &Attrs, bool SetTargetFeatures) { @@ -2927,10 +3037,6 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, llvm::StringMap<bool> FeatureMap; getContext().getFunctionFeatureMap(FeatureMap, GD); - // Produce the canonical string for this set of features. - for (const llvm::StringMap<bool>::value_type &Entry : FeatureMap) - Features.push_back((Entry.getValue() ? "+" : "-") + Entry.getKey().str()); - // Now add the target-cpu and target-features to the function. // While we populated the feature map above, we still need to // get and parse the target attribute so we can get the cpu for @@ -2953,10 +3059,34 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, // favor this processor. TuneCPU = SD->getCPUName(GD.getMultiVersionIndex())->getName(); } + + // For AMDGPU, only emit delta features (features that differ from the + // target CPU's defaults). Other targets might want to follow a similar + // pattern. + if (getTarget().getTriple().isAMDGPU()) { + Features = getFeatureDeltaFromDefault(*this, TargetCPU, FeatureMap); + } else { + // Produce the canonical string for this set of features. + for (const llvm::StringMap<bool>::value_type &Entry : FeatureMap) + Features.push_back((Entry.getValue() ? "+" : "-") + + Entry.getKey().str()); + } } else { // Otherwise just add the existing target cpu and target features to the // function. - Features = getTarget().getTargetOpts().Features; + if (SetTargetFeatures && getTarget().getTriple().isAMDGPU()) { + llvm::StringMap<bool> FeatureMap; + if (FD) { + getContext().getFunctionFeatureMap(FeatureMap, GD); + } else { + getTarget().initFeatureMap(FeatureMap, getContext().getDiagnostics(), + TargetCPU, + getTarget().getTargetOpts().Features); + } + Features = getFeatureDeltaFromDefault(*this, TargetCPU, FeatureMap); + } else { + Features = getTarget().getTargetOpts().Features; + } } if (!TargetCPU.empty()) { @@ -3186,7 +3316,8 @@ void CodeGenModule::finalizeKCFITypes() { continue; std::string Asm = (".weak __kcfi_typeid_" + Name + "\n.set __kcfi_typeid_" + - Name + ", " + Twine(Type->getZExtValue()) + "\n") + Name + ", " + Twine(Type->getZExtValue()) + " /* " + + Twine(Type->getSExtValue()) + " */\n") .str(); M.appendModuleInlineAsm(Asm); } @@ -4104,6 +4235,38 @@ template <typename AttrT> static bool hasImplicitAttr(const ValueDecl *D) { return D->isImplicit(); } +static bool shouldSkipAliasEmission(const CodeGenModule &CGM, + const ValueDecl *Global) { + const LangOptions &LangOpts = CGM.getLangOpts(); + if (!LangOpts.OpenMPIsTargetDevice && !LangOpts.CUDA) + return false; + + const auto *AA = Global->getAttr<AliasAttr>(); + GlobalDecl AliaseeGD; + + // Check if the aliasee exists, if the aliasee is not found, skip the alias + // emission. This is executed for both the host and device. + if (!CGM.lookupRepresentativeDecl(AA->getAliasee(), AliaseeGD)) + return true; + + const auto *AliaseeDecl = dyn_cast<ValueDecl>(AliaseeGD.getDecl()); + if (LangOpts.OpenMPIsTargetDevice) + return !AliaseeDecl || + !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(AliaseeDecl); + + // CUDA / HIP + const bool HasDeviceAttr = Global->hasAttr<CUDADeviceAttr>(); + const bool AliaseeHasDeviceAttr = + AliaseeDecl && AliaseeDecl->hasAttr<CUDADeviceAttr>(); + + if (LangOpts.CUDAIsDevice) + return !HasDeviceAttr || !AliaseeHasDeviceAttr; + + // CUDA / HIP Host + // we know that the aliasee exists from above, so we know to emit + return false; +} + bool CodeGenModule::shouldEmitCUDAGlobalVar(const VarDecl *Global) const { assert(LangOpts.CUDA && "Should not be called by non-CUDA languages"); // We need to emit host-side 'shadows' for all global @@ -4126,8 +4289,11 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // If this is an alias definition (which otherwise looks like a declaration) // emit it now. - if (Global->hasAttr<AliasAttr>()) + if (Global->hasAttr<AliasAttr>()) { + if (shouldSkipAliasEmission(*this, Global)) + return; return EmitAliasDefinition(GD); + } // IFunc like an alias whose value is resolved at runtime by calling resolver. if (Global->hasAttr<IFuncAttr>()) @@ -4612,6 +4778,7 @@ void CodeGenModule::emitMultiVersionFunctions() { // in this TU. For other architectures it is always emitted. bool ShouldEmitResolver = !getTarget().getTriple().isAArch64(); SmallVector<CodeGenFunction::FMVResolverOption, 10> Options; + llvm::DenseMap<llvm::Function *, const FunctionDecl *> DeclMap; getContext().forEachMultiversionedFunctionVersion( FD, [&](const FunctionDecl *CurFD) { @@ -4622,11 +4789,13 @@ void CodeGenModule::emitMultiVersionFunctions() { assert(getTarget().getTriple().isX86() && "Unsupported target"); TA->getX86AddedFeatures(Feats); llvm::Function *Func = createFunction(CurFD); + DeclMap.insert({Func, CurFD}); Options.emplace_back(Func, Feats, TA->getX86Architecture()); } else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) { if (TVA->isDefaultVersion() && IsDefined) ShouldEmitResolver = true; llvm::Function *Func = createFunction(CurFD); + DeclMap.insert({Func, CurFD}); char Delim = getTarget().getTriple().isAArch64() ? '+' : ','; TVA->getFeatures(Feats, Delim); Options.emplace_back(Func, Feats); @@ -4637,6 +4806,7 @@ void CodeGenModule::emitMultiVersionFunctions() { if (TC->isDefaultVersion(I) && IsDefined) ShouldEmitResolver = true; llvm::Function *Func = createFunction(CurFD, I); + DeclMap.insert({Func, CurFD}); Feats.clear(); if (getTarget().getTriple().isX86()) { TC->getX86Feature(Feats, I); @@ -4682,6 +4852,24 @@ void CodeGenModule::emitMultiVersionFunctions() { const CodeGenFunction::FMVResolverOption &RHS) { return getFMVPriority(TI, LHS).ugt(getFMVPriority(TI, RHS)); }); + + // Diagnose unreachable function versions. + if (getTarget().getTriple().isAArch64()) { + for (auto I = Options.begin() + 1, E = Options.end(); I != E; ++I) { + llvm::APInt RHS = llvm::AArch64::getCpuSupportsMask(I->Features); + if (std::any_of(Options.begin(), I, [RHS](auto RO) { + llvm::APInt LHS = llvm::AArch64::getCpuSupportsMask(RO.Features); + return LHS.isSubsetOf(RHS); + })) { + Diags.Report(DeclMap[I->Function]->getLocation(), + diag::warn_unreachable_version) + << I->Function->getName(); + assert(I->Function->user_empty() && "unexpected users"); + I->Function->eraseFromParent(); + I->Function = nullptr; + } + } + } CodeGenFunction CGF(*this); CGF.EmitMultiVersionResolver(ResolverFunc, Options); @@ -4935,6 +5123,11 @@ void CodeGenModule::setMultiVersionResolverAttributes(llvm::Function *Resolver, setDSOLocal(Resolver); + // The resolver must be exempt from sanitizer instrumentation, as it can run + // before the sanitizer is initialized. + // (https://github.com/llvm/llvm-project/issues/163369) + Resolver->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + // Set the default target-specific attributes, such as PAC and BTI ones on // AArch64. Not passing Decl to prevent setting unrelated attributes, // as Resolver can be shared by multiple declarations. @@ -5528,11 +5721,9 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, D ? D->getType().getAddressSpace() : (LangOpts.OpenCL ? LangAS::opencl_global : LangAS::Default); assert(getContext().getTargetAddressSpace(ExpectedAS) == TargetAS); - if (DAddrSpace != ExpectedAS) { - return getTargetCodeGenInfo().performAddrSpaceCast( - *this, GV, DAddrSpace, - llvm::PointerType::get(getLLVMContext(), TargetAS)); - } + if (DAddrSpace != ExpectedAS) + return performAddrSpaceCast( + GV, llvm::PointerType::get(getLLVMContext(), TargetAS)); return GV; } @@ -5764,11 +5955,10 @@ castStringLiteralToDefaultAddressSpace(CodeGenModule &CGM, if (!CGM.getLangOpts().OpenCL) { auto AS = CGM.GetGlobalConstantAddressSpace(); if (AS != LangAS::Default) - Cast = CGM.getTargetCodeGenInfo().performAddrSpaceCast( - CGM, GV, AS, - llvm::PointerType::get( - CGM.getLLVMContext(), - CGM.getContext().getTargetAddressSpace(LangAS::Default))); + Cast = CGM.performAddrSpaceCast( + GV, llvm::PointerType::get( + CGM.getLLVMContext(), + CGM.getContext().getTargetAddressSpace(LangAS::Default))); } return Cast; } @@ -5917,7 +6107,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, (D->getType()->isHLSLResourceRecord() || D->getType()->isHLSLResourceRecordArray())) { Init = llvm::PoisonValue::get(getTypes().ConvertType(ASTTy)); - NeedsGlobalCtor = D->getType()->isHLSLResourceRecord(); + NeedsGlobalCtor = D->getType()->isHLSLResourceRecord() || + D->getStorageClass() == SC_Static; } else if (D->hasAttr<LoaderUninitializedAttr>()) { Init = llvm::UndefValue::get(getTypes().ConvertTypeForMem(ASTTy)); } else if (!InitExpr) { @@ -6041,9 +6232,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, getCUDARuntime().handleVarRegistration(D, *GV); } - if (LangOpts.HLSL && GetGlobalVarAddressSpace(D) == LangAS::hlsl_input) { + if (LangOpts.HLSL && + hlsl::isInitializedByPipeline(GetGlobalVarAddressSpace(D))) { // HLSL Input variables are considered to be set by the driver/pipeline, but - // only visible to a single thread/wave. + // only visible to a single thread/wave. Push constants are also externally + // initialized, but constant, hence cross-wave visibility is not relevant. GV->setExternallyInitialized(true); } else { GV->setInitializer(Init); @@ -6094,10 +6287,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, !D->hasAttr<ConstInitAttr>()) Linkage = llvm::GlobalValue::InternalLinkage; - // HLSL variables in the input address space maps like memory-mapped - // variables. Even if they are 'static', they are externally initialized and - // read/write by the hardware/driver/pipeline. - if (LangOpts.HLSL && GetGlobalVarAddressSpace(D) == LangAS::hlsl_input) + // HLSL variables in the input or push-constant address space maps are like + // memory-mapped variables. Even if they are 'static', they are externally + // initialized and read/write by the hardware/driver/pipeline. + if (LangOpts.HLSL && + hlsl::isInitializedByPipeline(GetGlobalVarAddressSpace(D))) Linkage = llvm::GlobalValue::ExternalLinkage; GV->setLinkage(Linkage); @@ -7187,11 +7381,10 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary( setTLSMode(GV, *VD); llvm::Constant *CV = GV; if (AddrSpace != LangAS::Default) - CV = getTargetCodeGenInfo().performAddrSpaceCast( - *this, GV, AddrSpace, - llvm::PointerType::get( - getLLVMContext(), - getContext().getTargetAddressSpace(LangAS::Default))); + CV = performAddrSpaceCast( + GV, llvm::PointerType::get( + getLLVMContext(), + getContext().getTargetAddressSpace(LangAS::Default))); // Update the map with the new temporary. If we created a placeholder above, // replace it with the new global now. @@ -8198,11 +8391,7 @@ bool CodeGenModule::stopAutoInit() { return true; } if (!NumAutoVarInit) { - unsigned DiagID = getDiags().getCustomDiagID( - DiagnosticsEngine::Warning, - "-ftrivial-auto-var-init-stop-after=%0 has been enabled to limit the " - "number of times ftrivial-auto-var-init=%1 gets applied."); - getDiags().Report(DiagID) + getDiags().Report(diag::warn_trivial_auto_var_limit) << StopAfter << (getContext().getLangOpts().getTrivialAutoVarInit() == LangOptions::TrivialAutoVarInitKind::Zero |
