diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index 78a9cb77ff7d9..e1c66ac18e7ac 100755 --- a/.ci/generate-buildkite-pipeline-premerge +++ b/.ci/generate-buildkite-pipeline-premerge @@ -68,7 +68,7 @@ function compute-projects-to-test() { done ;; clang) - for p in clang-tools-extra compiler-rt flang lldb cross-project-tests; do + for p in clang-tools-extra compiler-rt lldb cross-project-tests; do echo $p done ;; diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt index cc3a70fa35e0a..74907ad118d12 100644 --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -1,3 +1,5 @@ +set(LLVM_SUBPROJECT_TITLE "BOLT") + include(ExternalProject) set(BOLT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) @@ -121,7 +123,7 @@ option(BOLT_BUILD_TOOLS "Build the BOLT tools. If OFF, just generate build targets." ON) add_custom_target(bolt) -set_target_properties(bolt PROPERTIES FOLDER "BOLT") +set_target_properties(bolt PROPERTIES FOLDER "BOLT/Metatargets") add_llvm_install_targets(install-bolt DEPENDS bolt COMPONENT bolt) include_directories( diff --git a/bolt/cmake/modules/AddBOLT.cmake b/bolt/cmake/modules/AddBOLT.cmake index 1f69b9046320a..c7ac662c6b121 100644 --- a/bolt/cmake/modules/AddBOLT.cmake +++ b/bolt/cmake/modules/AddBOLT.cmake @@ -3,7 +3,6 @@ include(LLVMDistributionSupport) macro(add_bolt_executable name) add_llvm_executable(${name} ${ARGN}) - set_target_properties(${name} PROPERTIES FOLDER "BOLT") endmacro() macro(add_bolt_tool name) diff --git a/bolt/docs/BAT.md b/bolt/docs/BAT.md index 7ffb5d7c00816..817ad288aa34b 100644 --- a/bolt/docs/BAT.md +++ b/bolt/docs/BAT.md @@ -106,9 +106,14 @@ equals output offset. `BRANCHENTRY` bit denotes whether a given offset pair is a control flow source (branch or call instruction). If not set, it signifies a control flow target (basic block offset). + `InputAddr` is omitted for equal offsets in input and output function. In this case, `BRANCHENTRY` bits are encoded separately in a `BranchEntries` bitvector. +Deleted basic blocks are emitted as having `OutputOffset` equal to the size of +the function. They don't affect address translation and only participate in +input basic block mapping. + ### Secondary Entry Points table The table is emitted for hot fragments only. It contains `NumSecEntryPoints` offsets denoting secondary entry points, delta encoded, implicitly starting at zero. diff --git a/bolt/docs/CMakeLists.txt b/bolt/docs/CMakeLists.txt index b230512fe5717..12ae852566785 100644 --- a/bolt/docs/CMakeLists.txt +++ b/bolt/docs/CMakeLists.txt @@ -79,6 +79,7 @@ if (LLVM_ENABLE_DOXYGEN) COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating bolt doxygen documentation." VERBATIM) + set_target_properties(doxygen-bolt PROPERTIES FOLDER "BOLT/Docs") if (LLVM_BUILD_DOCS) add_dependencies(doxygen doxygen-bolt) diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index 75765819ac464..4ec3de3da1bf8 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -17,6 +17,7 @@ #include "bolt/Core/BinaryData.h" #include "bolt/Core/BinarySection.h" #include "bolt/Core/DebugData.h" +#include "bolt/Core/DynoStats.h" #include "bolt/Core/JumpTable.h" #include "bolt/Core/MCPlusBuilder.h" #include "bolt/RuntimeLibs/RuntimeLibrary.h" @@ -359,7 +360,7 @@ class BinaryContext { void setFileBuildID(StringRef ID) { FileBuildID = std::string(ID); } bool hasSymbolsWithFileName() const { return HasSymbolsWithFileName; } - void setHasSymbolsWithFileName(bool Value) { HasSymbolsWithFileName = true; } + void setHasSymbolsWithFileName(bool Value) { HasSymbolsWithFileName = Value; } /// Return true if relocations against symbol with a given name /// must be created. @@ -677,6 +678,9 @@ class BinaryContext { /// have an origin file name available. bool HasSymbolsWithFileName{false}; + /// Does the binary have BAT section. + bool HasBATSection{false}; + /// Sum of execution count of all functions uint64_t SumExecutionCount{0}; @@ -714,6 +718,9 @@ class BinaryContext { uint64_t NumStaleBlocksWithEqualIcount{0}; } Stats; + // Original binary execution count stats. + DynoStats InitialDynoStats; + // Address of the first allocated segment. uint64_t FirstAllocAddress{std::numeric_limits::max()}; @@ -1217,8 +1224,7 @@ class BinaryContext { /// Return a signed value of \p Size stored at \p Address. The address has /// to be a valid statically allocated address for the binary. - ErrorOr getSignedValueAtAddress(uint64_t Address, - size_t Size) const; + ErrorOr getSignedValueAtAddress(uint64_t Address, size_t Size) const; /// Special case of getUnsignedValueAtAddress() that uses a pointer size. ErrorOr getPointerAtAddress(uint64_t Address) const { diff --git a/bolt/include/bolt/Passes/BinaryPasses.h b/bolt/include/bolt/Passes/BinaryPasses.h index 5d7692559eda8..ad8473c4aae02 100644 --- a/bolt/include/bolt/Passes/BinaryPasses.h +++ b/bolt/include/bolt/Passes/BinaryPasses.h @@ -16,6 +16,7 @@ #include "bolt/Core/BinaryContext.h" #include "bolt/Core/BinaryFunction.h" #include "bolt/Core/DynoStats.h" +#include "bolt/Profile/BoltAddressTranslation.h" #include "llvm/Support/CommandLine.h" #include #include @@ -52,15 +53,31 @@ class BinaryFunctionPass { virtual Error runOnFunctions(BinaryContext &BC) = 0; }; +/// A pass to set initial program-wide dynostats. +class DynoStatsSetPass : public BinaryFunctionPass { +public: + DynoStatsSetPass() : BinaryFunctionPass(false) {} + + const char *getName() const override { + return "set dyno-stats before optimizations"; + } + + bool shouldPrint(const BinaryFunction &BF) const override { return false; } + + Error runOnFunctions(BinaryContext &BC) override { + BC.InitialDynoStats = getDynoStats(BC.getBinaryFunctions(), BC.isAArch64()); + return Error::success(); + } +}; + /// A pass to print program-wide dynostats. class DynoStatsPrintPass : public BinaryFunctionPass { protected: - DynoStats PrevDynoStats; std::string Title; public: - DynoStatsPrintPass(const DynoStats &PrevDynoStats, const char *Title) - : BinaryFunctionPass(false), PrevDynoStats(PrevDynoStats), Title(Title) {} + DynoStatsPrintPass(const char *Title) + : BinaryFunctionPass(false), Title(Title) {} const char *getName() const override { return "print dyno-stats after optimizations"; @@ -69,6 +86,7 @@ class DynoStatsPrintPass : public BinaryFunctionPass { bool shouldPrint(const BinaryFunction &BF) const override { return false; } Error runOnFunctions(BinaryContext &BC) override { + const DynoStats PrevDynoStats = BC.InitialDynoStats; const DynoStats NewDynoStats = getDynoStats(BC.getBinaryFunctions(), BC.isAArch64()); const bool Changed = (NewDynoStats != PrevDynoStats); @@ -399,8 +417,11 @@ class PrintProfileStats : public BinaryFunctionPass { /// Prints a list of the top 100 functions sorted by a set of /// dyno stats categories. class PrintProgramStats : public BinaryFunctionPass { + BoltAddressTranslation *BAT = nullptr; + public: - explicit PrintProgramStats() : BinaryFunctionPass(false) {} + explicit PrintProgramStats(BoltAddressTranslation *BAT = nullptr) + : BinaryFunctionPass(false), BAT(BAT) {} const char *getName() const override { return "print-stats"; } bool shouldPrint(const BinaryFunction &) const override { return false; } diff --git a/bolt/include/bolt/Passes/MCF.h b/bolt/include/bolt/Passes/MCF.h index feac7f88ac11e..3fe674463bf13 100644 --- a/bolt/include/bolt/Passes/MCF.h +++ b/bolt/include/bolt/Passes/MCF.h @@ -9,20 +9,14 @@ #ifndef BOLT_PASSES_MCF_H #define BOLT_PASSES_MCF_H +#include "bolt/Passes/BinaryPasses.h" +#include "llvm/Support/CommandLine.h" + namespace llvm { namespace bolt { -class BinaryFunction; class DataflowInfoManager; -enum MCFCostFunction : char { - MCF_DISABLE = 0, - MCF_LINEAR, - MCF_QUADRATIC, - MCF_LOG, - MCF_BLAMEFTS -}; - /// Implement the idea in "SamplePGO - The Power of Profile Guided Optimizations /// without the Usability Burden" by Diego Novillo to make basic block counts /// equal if we show that A dominates B, B post-dominates A and they are in the @@ -31,23 +25,18 @@ void equalizeBBCounts(DataflowInfoManager &Info, BinaryFunction &BF); /// Fill edge counts based on the basic block count. Used in nonLBR mode when /// we only have bb count. -void estimateEdgeCounts(BinaryFunction &BF); - -/// Entry point for computing a min-cost flow for the CFG with the goal -/// of fixing the flow of the CFG edges, that is, making sure it obeys the -/// flow-conservation equation SumInEdges = SumOutEdges. -/// -/// To do this, we create an instance of the min-cost flow problem in a -/// similar way as the one discussed in the work of Roy Levin "Completing -/// Incomplete Edge Profile by Applying Minimum Cost Circulation Algorithms". -/// We do a few things differently, though. We don't populate edge counts using -/// weights coming from a static branch prediction technique and we don't -/// use the same cost function. -/// -/// If cost function BlameFTs is used, assign all remaining flow to -/// fall-throughs. This is used when the sampling is based on taken branches -/// that do not account for them. -void solveMCF(BinaryFunction &BF, MCFCostFunction CostFunction); +class EstimateEdgeCounts : public BinaryFunctionPass { + void runOnFunction(BinaryFunction &BF); + +public: + explicit EstimateEdgeCounts(const cl::opt &PrintPass) + : BinaryFunctionPass(PrintPass) {} + + const char *getName() const override { return "estimate-edge-counts"; } + + /// Pass entry point + Error runOnFunctions(BinaryContext &BC) override; +}; } // end namespace bolt } // end namespace llvm diff --git a/bolt/include/bolt/Passes/StokeInfo.h b/bolt/include/bolt/Passes/StokeInfo.h index 76417e6a2c3ba..a18c2a05d0153 100644 --- a/bolt/include/bolt/Passes/StokeInfo.h +++ b/bolt/include/bolt/Passes/StokeInfo.h @@ -87,10 +87,10 @@ struct StokeFuncInfo { << "," << NumBlocks << "," << IsLoopFree << "," << NumLoops << "," << MaxLoopDepth << "," << HotSize << "," << TotalSize << "," << Score << "," << HasCall << ",\"{ "; - for (std::string S : DefIn) + for (const std::string &S : DefIn) Outfile << "%" << S << " "; Outfile << "}\",\"{ "; - for (std::string S : LiveOut) + for (const std::string &S : LiveOut) Outfile << "%" << S << " "; Outfile << "}\"," << HeapOut << "," << StackOut << "," << HasRipAddr << "," << Omitted << "\n"; diff --git a/bolt/include/bolt/Profile/BoltAddressTranslation.h b/bolt/include/bolt/Profile/BoltAddressTranslation.h index 68b993ee363cc..65b9ba874368f 100644 --- a/bolt/include/bolt/Profile/BoltAddressTranslation.h +++ b/bolt/include/bolt/Profile/BoltAddressTranslation.h @@ -70,7 +70,7 @@ class BinaryFunction; class BoltAddressTranslation { public: // In-memory representation of the address translation table - using MapTy = std::map; + using MapTy = std::multimap; // List of taken fall-throughs using FallthroughListTy = SmallVector, 16>; @@ -90,7 +90,7 @@ class BoltAddressTranslation { std::error_code parse(raw_ostream &OS, StringRef Buf); /// Dump the parsed address translation tables - void dump(raw_ostream &OS); + void dump(raw_ostream &OS) const; /// If the maps are loaded in memory, perform the lookup to translate LBR /// addresses in function located at \p FuncAddress. @@ -107,7 +107,12 @@ class BoltAddressTranslation { /// If available, fetch the address of the hot part linked to the cold part /// at \p Address. Return 0 otherwise. - uint64_t fetchParentAddress(uint64_t Address) const; + uint64_t fetchParentAddress(uint64_t Address) const { + auto Iter = ColdPartSource.find(Address); + if (Iter == ColdPartSource.end()) + return 0; + return Iter->second; + } /// True if the input binary has a translation table we can use to convert /// addresses when aggregating profile @@ -132,7 +137,8 @@ class BoltAddressTranslation { /// emitted for the start of the BB. More entries may be emitted to cover /// the location of calls or any instruction that may change control flow. void writeEntriesForBB(MapTy &Map, const BinaryBasicBlock &BB, - uint64_t FuncInputAddress, uint64_t FuncOutputAddress); + uint64_t FuncInputAddress, + uint64_t FuncOutputAddress) const; /// Write the serialized address translation table for a function. template @@ -147,7 +153,7 @@ class BoltAddressTranslation { /// Returns the bitmask with set bits corresponding to indices of BRANCHENTRY /// entries in function address translation map. - APInt calculateBranchEntriesBitMask(MapTy &Map, size_t EqualElems); + APInt calculateBranchEntriesBitMask(MapTy &Map, size_t EqualElems) const; /// Calculate the number of equal offsets (output = input - skew) in the /// beginning of the function. @@ -178,14 +184,9 @@ class BoltAddressTranslation { public: /// Map basic block input offset to a basic block index and hash pair. class BBHashMapTy { - class EntryTy { + struct EntryTy { unsigned Index; size_t Hash; - - public: - unsigned getBBIndex() const { return Index; } - size_t getBBHash() const { return Hash; } - EntryTy(unsigned Index, size_t Hash) : Index(Index), Hash(Hash) {} }; std::map Map; @@ -201,15 +202,15 @@ class BoltAddressTranslation { } unsigned getBBIndex(uint32_t BBInputOffset) const { - return getEntry(BBInputOffset).getBBIndex(); + return getEntry(BBInputOffset).Index; } size_t getBBHash(uint32_t BBInputOffset) const { - return getEntry(BBInputOffset).getBBHash(); + return getEntry(BBInputOffset).Hash; } void addEntry(uint32_t BBInputOffset, unsigned BBIndex, size_t BBHash) { - Map.emplace(BBInputOffset, EntryTy(BBIndex, BBHash)); + Map.emplace(BBInputOffset, EntryTy{BBIndex, BBHash}); } size_t getNumBasicBlocks() const { return Map.size(); } @@ -217,18 +218,14 @@ class BoltAddressTranslation { auto begin() const { return Map.begin(); } auto end() const { return Map.end(); } auto upper_bound(uint32_t Offset) const { return Map.upper_bound(Offset); } + auto size() const { return Map.size(); } }; /// Map function output address to its hash and basic blocks hash map. class FuncHashesTy { - class EntryTy { + struct EntryTy { size_t Hash; BBHashMapTy BBHashMap; - - public: - size_t getBFHash() const { return Hash; } - const BBHashMapTy &getBBHashMap() const { return BBHashMap; } - EntryTy(size_t Hash) : Hash(Hash) {} }; std::unordered_map Map; @@ -240,15 +237,15 @@ class BoltAddressTranslation { public: size_t getBFHash(uint64_t FuncOutputAddress) const { - return getEntry(FuncOutputAddress).getBFHash(); + return getEntry(FuncOutputAddress).Hash; } const BBHashMapTy &getBBHashMap(uint64_t FuncOutputAddress) const { - return getEntry(FuncOutputAddress).getBBHashMap(); + return getEntry(FuncOutputAddress).BBHashMap; } void addEntry(uint64_t FuncOutputAddress, size_t BFHash) { - Map.emplace(FuncOutputAddress, EntryTy(BFHash)); + Map.emplace(FuncOutputAddress, EntryTy{BFHash, BBHashMapTy()}); } size_t getNumFunctions() const { return Map.size(); }; @@ -256,7 +253,7 @@ class BoltAddressTranslation { size_t getNumBasicBlocks() const { size_t NumBasicBlocks{0}; for (auto &I : Map) - NumBasicBlocks += I.second.getBBHashMap().getNumBasicBlocks(); + NumBasicBlocks += I.second.BBHashMap.getNumBasicBlocks(); return NumBasicBlocks; } }; @@ -278,7 +275,9 @@ class BoltAddressTranslation { /// Returns the number of basic blocks in a function. size_t getNumBasicBlocks(uint64_t OutputAddress) const { - return NumBasicBlocksMap.at(OutputAddress); + auto It = NumBasicBlocksMap.find(OutputAddress); + assert(It != NumBasicBlocksMap.end()); + return It->second; } private: diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h index c158a9bb3e3f2..6453b3070ceb8 100644 --- a/bolt/include/bolt/Profile/DataAggregator.h +++ b/bolt/include/bolt/Profile/DataAggregator.h @@ -15,6 +15,7 @@ #define BOLT_PROFILE_DATA_AGGREGATOR_H #include "bolt/Profile/DataReader.h" +#include "bolt/Profile/YAMLProfileWriter.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/Program.h" @@ -248,7 +249,7 @@ class DataAggregator : public DataReader { BinaryFunction *getBATParentFunction(const BinaryFunction &Func) const; /// Retrieve the location name to be used for samples recorded in \p Func. - StringRef getLocationName(const BinaryFunction &Func) const; + static StringRef getLocationName(const BinaryFunction &Func, bool BAT); /// Semantic actions - parser hooks to interpret parsed perf samples /// Register a sample (non-LBR mode), i.e. a new hit at \p Address @@ -490,6 +491,8 @@ class DataAggregator : public DataReader { /// Parse the output generated by "perf buildid-list" to extract build-ids /// and return a file name matching a given \p FileBuildID. std::optional getFileNameForBuildID(StringRef FileBuildID); + + friend class YAMLProfileWriter; }; } // namespace bolt } // namespace llvm diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index ad2eb18caf109..db02dc0fae4ee 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -142,7 +142,7 @@ BinaryContext::BinaryContext(std::unique_ptr Ctx, AsmInfo(std::move(AsmInfo)), MII(std::move(MII)), STI(std::move(STI)), InstPrinter(std::move(InstPrinter)), MIA(std::move(MIA)), MIB(std::move(MIB)), MRI(std::move(MRI)), DisAsm(std::move(DisAsm)), - Logger(Logger) { + Logger(Logger), InitialDynoStats(isAArch64()) { Relocation::Arch = this->TheTriple->getArch(); RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86; PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize; @@ -934,10 +934,13 @@ std::string BinaryContext::generateJumpTableName(const BinaryFunction &BF, uint64_t Offset = 0; if (const JumpTable *JT = BF.getJumpTableContainingAddress(Address)) { Offset = Address - JT->getAddress(); - auto Itr = JT->Labels.find(Offset); - if (Itr != JT->Labels.end()) - return std::string(Itr->second->getName()); - Id = JumpTableIds.at(JT->getAddress()); + auto JTLabelsIt = JT->Labels.find(Offset); + if (JTLabelsIt != JT->Labels.end()) + return std::string(JTLabelsIt->second->getName()); + + auto JTIdsIt = JumpTableIds.find(JT->getAddress()); + assert(JTIdsIt != JumpTableIds.end()); + Id = JTIdsIt->second; } else { Id = JumpTableIds[Address] = BF.JumpTables.size(); } @@ -1322,7 +1325,9 @@ void BinaryContext::processInterproceduralReferences() { InterproceduralReferences) { BinaryFunction &Function = *It.first; uint64_t Address = It.second; - if (!Address || Function.isIgnored()) + // Process interprocedural references from ignored functions in BAT mode + // (non-simple in non-relocation mode) to properly register entry points + if (!Address || (Function.isIgnored() && !HasBATSection)) continue; BinaryFunction *TargetFunction = @@ -2212,8 +2217,8 @@ ErrorOr BinaryContext::getUnsignedValueAtAddress(uint64_t Address, return DE.getUnsigned(&ValueOffset, Size); } -ErrorOr BinaryContext::getSignedValueAtAddress(uint64_t Address, - size_t Size) const { +ErrorOr BinaryContext::getSignedValueAtAddress(uint64_t Address, + size_t Size) const { const ErrorOr Section = getSectionForAddress(Address); if (!Section) return std::make_error_code(std::errc::bad_address); diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp index 6f86ddc774544..0b44acb0816f2 100644 --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -813,7 +813,9 @@ void BinaryEmitter::emitJumpTable(const JumpTable &JT, MCSection *HotSection, // determining its destination. std::map LabelCounts; if (opts::JumpTables > JTS_SPLIT && !JT.Counts.empty()) { - MCSymbol *CurrentLabel = JT.Labels.at(0); + auto It = JT.Labels.find(0); + assert(It != JT.Labels.end()); + MCSymbol *CurrentLabel = It->second; uint64_t CurrentLabelCount = 0; for (unsigned Index = 0; Index < JT.Entries.size(); ++Index) { auto LI = JT.Labels.find(Index * JT.EntrySize); diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index 10b93e702984f..c897392f2a574 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -851,15 +851,19 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, return IndirectBranchType::UNKNOWN; } - // RIP-relative addressing should be converted to symbol form by now - // in processed instructions (but not in jump). - if (DispExpr) { + auto getExprValue = [&](const MCExpr *Expr) { const MCSymbol *TargetSym; uint64_t TargetOffset; - std::tie(TargetSym, TargetOffset) = BC.MIB->getTargetSymbolInfo(DispExpr); + std::tie(TargetSym, TargetOffset) = BC.MIB->getTargetSymbolInfo(Expr); ErrorOr SymValueOrError = BC.getSymbolValue(*TargetSym); - assert(SymValueOrError && "global symbol needs a value"); - ArrayStart = *SymValueOrError + TargetOffset; + assert(SymValueOrError && "Global symbol needs a value"); + return *SymValueOrError + TargetOffset; + }; + + // RIP-relative addressing should be converted to symbol form by now + // in processed instructions (but not in jump). + if (DispExpr) { + ArrayStart = getExprValue(DispExpr); BaseRegNum = BC.MIB->getNoRegister(); if (BC.isAArch64()) { ArrayStart &= ~0xFFFULL; @@ -1666,7 +1670,8 @@ void BinaryFunction::postProcessEntryPoints() { // In non-relocation mode there's potentially an external undetectable // reference to the entry point and hence we cannot move this entry // point. Optimizing without moving could be difficult. - if (!BC.HasRelocations) + // In BAT mode, register any known entry points for CFG construction. + if (!BC.HasRelocations && !BC.HasBATSection) setSimple(false); const uint32_t Offset = KV.first; @@ -3697,6 +3702,13 @@ BinaryFunction::BasicBlockListType BinaryFunction::dfs() const { size_t BinaryFunction::computeHash(bool UseDFS, HashFunction HashFunction, OperandHashFuncTy OperandHashFunc) const { + LLVM_DEBUG({ + dbgs() << "BOLT-DEBUG: computeHash " << getPrintName() << ' ' + << (UseDFS ? "dfs" : "bin") << " order " + << (HashFunction == HashFunction::StdHash ? "std::hash" : "xxh3") + << '\n'; + }); + if (size() == 0) return 0; diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp index 049244c4b5151..791cbc6df0828 100644 --- a/bolt/lib/Core/DebugNames.cpp +++ b/bolt/lib/Core/DebugNames.cpp @@ -112,8 +112,6 @@ void DWARF5AcceleratorTable::addUnit(DWARFUnit &Unit, // Returns true if DW_TAG_variable should be included in .debug-names based on // section 6.1.1.1 for DWARF5 spec. static bool shouldIncludeVariable(const DWARFUnit &Unit, const DIE &Die) { - if (Die.findAttribute(dwarf::Attribute::DW_AT_declaration)) - return false; const DIEValue LocAttrInfo = Die.findAttribute(dwarf::Attribute::DW_AT_location); if (!LocAttrInfo) @@ -148,6 +146,8 @@ static bool shouldIncludeVariable(const DWARFUnit &Unit, const DIE &Die) { bool static canProcess(const DWARFUnit &Unit, const DIE &Die, std::string &NameToUse, const bool TagsOnly) { + if (Die.findAttribute(dwarf::Attribute::DW_AT_declaration)) + return false; switch (Die.getTag()) { case dwarf::DW_TAG_base_type: case dwarf::DW_TAG_class_type: diff --git a/bolt/lib/Core/DynoStats.cpp b/bolt/lib/Core/DynoStats.cpp index 5de0f9e0d6b8c..1d9818777596e 100644 --- a/bolt/lib/Core/DynoStats.cpp +++ b/bolt/lib/Core/DynoStats.cpp @@ -114,8 +114,9 @@ void DynoStats::print(raw_ostream &OS, const DynoStats *Other, for (auto &Stat : llvm::reverse(SortedHistogram)) { OS << format("%20s,%'18lld", Printer->getOpcodeName(Stat.second).data(), Stat.first * opts::DynoStatsScale); - - MaxOpcodeHistogramTy MaxMultiMap = OpcodeHistogram.at(Stat.second).second; + auto It = OpcodeHistogram.find(Stat.second); + assert(It != OpcodeHistogram.end()); + MaxOpcodeHistogramTy MaxMultiMap = It->second.second; // Start with function name:BB offset with highest execution count. for (auto &Max : llvm::reverse(MaxMultiMap)) { OS << format(", %'18lld, ", Max.first * opts::DynoStatsScale) diff --git a/bolt/lib/Passes/BinaryFunctionCallGraph.cpp b/bolt/lib/Passes/BinaryFunctionCallGraph.cpp index 2373710c9edd6..bbcc9751c0cbe 100644 --- a/bolt/lib/Passes/BinaryFunctionCallGraph.cpp +++ b/bolt/lib/Passes/BinaryFunctionCallGraph.cpp @@ -56,7 +56,9 @@ std::deque BinaryFunctionCallGraph::buildTraversalOrder() { std::stack Worklist; for (BinaryFunction *Func : Funcs) { - const NodeId Id = FuncToNodeId.at(Func); + auto It = FuncToNodeId.find(Func); + assert(It != FuncToNodeId.end()); + const NodeId Id = It->second; Worklist.push(Id); NodeStatus[Id] = NEW; } diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp index 298ba29ff5b3f..2810f723719d0 100644 --- a/bolt/lib/Passes/BinaryPasses.cpp +++ b/bolt/lib/Passes/BinaryPasses.cpp @@ -1390,9 +1390,19 @@ Error PrintProgramStats::runOnFunctions(BinaryContext &BC) { if (Function.isPLTFunction()) continue; + // Adjustment for BAT mode: the profile for BOLT split fragments is combined + // so only count the hot fragment. + const uint64_t Address = Function.getAddress(); + bool IsHotParentOfBOLTSplitFunction = !Function.getFragments().empty() && + BAT && BAT->isBATFunction(Address) && + !BAT->fetchParentAddress(Address); + ++NumRegularFunctions; - if (!Function.isSimple()) { + // In BOLTed binaries split functions are non-simple (due to non-relocation + // mode), but the original function is known to be simple and we have a + // valid profile for it. + if (!Function.isSimple() && !IsHotParentOfBOLTSplitFunction) { if (Function.hasProfile()) ++NumNonSimpleProfiledFunctions; continue; @@ -1553,23 +1563,28 @@ Error PrintProgramStats::runOnFunctions(BinaryContext &BC) { const bool Ascending = opts::DynoStatsSortOrderOpt == opts::DynoStatsSortOrder::Ascending; - if (SortAll) { - llvm::stable_sort(Functions, - [Ascending, &Stats](const BinaryFunction *A, - const BinaryFunction *B) { - return Ascending ? Stats.at(A) < Stats.at(B) - : Stats.at(B) < Stats.at(A); - }); - } else { - llvm::stable_sort( - Functions, [Ascending, &Stats](const BinaryFunction *A, - const BinaryFunction *B) { - const DynoStats &StatsA = Stats.at(A); - const DynoStats &StatsB = Stats.at(B); - return Ascending ? StatsA.lessThan(StatsB, opts::PrintSortedBy) - : StatsB.lessThan(StatsA, opts::PrintSortedBy); - }); - } + std::function + DynoStatsComparator = + SortAll ? [](const DynoStats &StatsA, + const DynoStats &StatsB) { return StatsA < StatsB; } + : [](const DynoStats &StatsA, const DynoStats &StatsB) { + return StatsA.lessThan(StatsB, opts::PrintSortedBy); + }; + + llvm::stable_sort(Functions, + [Ascending, &Stats, DynoStatsComparator]( + const BinaryFunction *A, const BinaryFunction *B) { + auto StatsItr = Stats.find(A); + assert(StatsItr != Stats.end()); + const DynoStats &StatsA = StatsItr->second; + + StatsItr = Stats.find(B); + assert(StatsItr != Stats.end()); + const DynoStats &StatsB = StatsItr->second; + + return Ascending ? DynoStatsComparator(StatsA, StatsB) + : DynoStatsComparator(StatsB, StatsA); + }); BC.outs() << "BOLT-INFO: top functions sorted by "; if (SortAll) { diff --git a/bolt/lib/Passes/CacheMetrics.cpp b/bolt/lib/Passes/CacheMetrics.cpp index b02d4303110b3..21b420a5c2b01 100644 --- a/bolt/lib/Passes/CacheMetrics.cpp +++ b/bolt/lib/Passes/CacheMetrics.cpp @@ -67,7 +67,20 @@ calcTSPScore(const std::vector &BinaryFunctions, for (BinaryBasicBlock *DstBB : SrcBB->successors()) { if (SrcBB != DstBB && BI->Count != BinaryBasicBlock::COUNT_NO_PROFILE) { JumpCount += BI->Count; - if (BBAddr.at(SrcBB) + BBSize.at(SrcBB) == BBAddr.at(DstBB)) + + auto BBAddrIt = BBAddr.find(SrcBB); + assert(BBAddrIt != BBAddr.end()); + uint64_t SrcBBAddr = BBAddrIt->second; + + auto BBSizeIt = BBSize.find(SrcBB); + assert(BBSizeIt != BBSize.end()); + uint64_t SrcBBSize = BBSizeIt->second; + + BBAddrIt = BBAddr.find(DstBB); + assert(BBAddrIt != BBAddr.end()); + uint64_t DstBBAddr = BBAddrIt->second; + + if (SrcBBAddr + SrcBBSize == DstBBAddr) Score += BI->Count; } ++BI; @@ -149,20 +162,28 @@ double expectedCacheHitRatio( for (BinaryFunction *BF : BinaryFunctions) { if (BF->getLayout().block_empty()) continue; - const uint64_t Page = - BBAddr.at(BF->getLayout().block_front()) / ITLBPageSize; - PageSamples[Page] += FunctionSamples.at(BF); + auto BBAddrIt = BBAddr.find(BF->getLayout().block_front()); + assert(BBAddrIt != BBAddr.end()); + const uint64_t Page = BBAddrIt->second / ITLBPageSize; + + auto FunctionSamplesIt = FunctionSamples.find(BF); + assert(FunctionSamplesIt != FunctionSamples.end()); + PageSamples[Page] += FunctionSamplesIt->second; } // Computing the expected number of misses for every function double Misses = 0; for (BinaryFunction *BF : BinaryFunctions) { // Skip the function if it has no samples - if (BF->getLayout().block_empty() || FunctionSamples.at(BF) == 0.0) + auto FunctionSamplesIt = FunctionSamples.find(BF); + assert(FunctionSamplesIt != FunctionSamples.end()); + double Samples = FunctionSamplesIt->second; + if (BF->getLayout().block_empty() || Samples == 0.0) continue; - double Samples = FunctionSamples.at(BF); - const uint64_t Page = - BBAddr.at(BF->getLayout().block_front()) / ITLBPageSize; + + auto BBAddrIt = BBAddr.find(BF->getLayout().block_front()); + assert(BBAddrIt != BBAddr.end()); + const uint64_t Page = BBAddrIt->second / ITLBPageSize; // The probability that the page is not present in the cache const double MissProb = pow(1.0 - PageSamples[Page] / TotalSamples, ITLBEntries); @@ -170,8 +191,10 @@ double expectedCacheHitRatio( // Processing all callers of the function for (std::pair Pair : Calls[BF]) { BinaryFunction *SrcFunction = Pair.first; - const uint64_t SrcPage = - BBAddr.at(SrcFunction->getLayout().block_front()) / ITLBPageSize; + + BBAddrIt = BBAddr.find(SrcFunction->getLayout().block_front()); + assert(BBAddrIt != BBAddr.end()); + const uint64_t SrcPage = BBAddrIt->second / ITLBPageSize; // Is this a 'long' or a 'short' call? if (Page != SrcPage) { // This is a miss diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp index 84e7d97067b0c..f004a8eeea185 100644 --- a/bolt/lib/Passes/Inliner.cpp +++ b/bolt/lib/Passes/Inliner.cpp @@ -355,7 +355,9 @@ Inliner::inlineCall(BinaryBasicBlock &CallerBB, std::vector Successors(BB.succ_size()); llvm::transform(BB.successors(), Successors.begin(), [&InlinedBBMap](const BinaryBasicBlock *BB) { - return InlinedBBMap.at(BB); + auto It = InlinedBBMap.find(BB); + assert(It != InlinedBBMap.end()); + return It->second; }); if (CallerFunction.hasValidProfile() && Callee.hasValidProfile()) diff --git a/bolt/lib/Passes/MCF.cpp b/bolt/lib/Passes/MCF.cpp index c3898d2dce989..77dea7369140e 100644 --- a/bolt/lib/Passes/MCF.cpp +++ b/bolt/lib/Passes/MCF.cpp @@ -12,9 +12,11 @@ #include "bolt/Passes/MCF.h" #include "bolt/Core/BinaryFunction.h" +#include "bolt/Core/ParallelUtilities.h" #include "bolt/Passes/DataflowInfoManager.h" #include "bolt/Utils/CommandLineOpts.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/CommandLine.h" #include #include @@ -29,19 +31,10 @@ namespace opts { extern cl::OptionCategory BoltOptCategory; -extern cl::opt TimeOpts; - static cl::opt IterativeGuess( "iterative-guess", cl::desc("in non-LBR mode, guess edge counts using iterative technique"), cl::Hidden, cl::cat(BoltOptCategory)); - -static cl::opt UseRArcs( - "mcf-use-rarcs", - cl::desc("in MCF, consider the possibility of cancelling flow to balance " - "edges"), - cl::Hidden, cl::cat(BoltOptCategory)); - } // namespace opts namespace llvm { @@ -441,7 +434,7 @@ void equalizeBBCounts(DataflowInfoManager &Info, BinaryFunction &BF) { } } -void estimateEdgeCounts(BinaryFunction &BF) { +void EstimateEdgeCounts::runOnFunction(BinaryFunction &BF) { EdgeWeightMap PredEdgeWeights; EdgeWeightMap SuccEdgeWeights; if (!opts::IterativeGuess) { @@ -462,8 +455,24 @@ void estimateEdgeCounts(BinaryFunction &BF) { recalculateBBCounts(BF, /*AllEdges=*/false); } -void solveMCF(BinaryFunction &BF, MCFCostFunction CostFunction) { - llvm_unreachable("not implemented"); +Error EstimateEdgeCounts::runOnFunctions(BinaryContext &BC) { + if (llvm::none_of(llvm::make_second_range(BC.getBinaryFunctions()), + [](const BinaryFunction &BF) { + return BF.getProfileFlags() == BinaryFunction::PF_SAMPLE; + })) + return Error::success(); + + ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) { + runOnFunction(BF); + }; + ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) { + return BF.getProfileFlags() != BinaryFunction::PF_SAMPLE; + }; + + ParallelUtilities::runOnEachFunction( + BC, ParallelUtilities::SchedulingPolicy::SP_BB_QUADRATIC, WorkFun, + SkipFunc, "EstimateEdgeCounts"); + return Error::success(); } } // namespace bolt diff --git a/bolt/lib/Profile/BoltAddressTranslation.cpp b/bolt/lib/Profile/BoltAddressTranslation.cpp index 7cfb9c132c2c6..cdfca2b9871ac 100644 --- a/bolt/lib/Profile/BoltAddressTranslation.cpp +++ b/bolt/lib/Profile/BoltAddressTranslation.cpp @@ -20,10 +20,9 @@ namespace bolt { const char *BoltAddressTranslation::SECTION_NAME = ".note.bolt_bat"; -void BoltAddressTranslation::writeEntriesForBB(MapTy &Map, - const BinaryBasicBlock &BB, - uint64_t FuncInputAddress, - uint64_t FuncOutputAddress) { +void BoltAddressTranslation::writeEntriesForBB( + MapTy &Map, const BinaryBasicBlock &BB, uint64_t FuncInputAddress, + uint64_t FuncOutputAddress) const { const uint64_t BBOutputOffset = BB.getOutputAddressRange().first - FuncOutputAddress; const uint32_t BBInputOffset = BB.getInputOffset(); @@ -55,7 +54,7 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map, // and this deleted block will both share the same output address (the same // key), and we need to map back. We choose here to privilege the successor by // allowing it to overwrite the previously inserted key in the map. - Map[BBOutputOffset] = BBInputOffset << 1; + Map.emplace(BBOutputOffset, BBInputOffset << 1); const auto &IOAddressMap = BB.getFunction()->getBinaryContext().getIOAddressMap(); @@ -72,8 +71,7 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map, LLVM_DEBUG(dbgs() << " Key: " << Twine::utohexstr(OutputOffset) << " Val: " << Twine::utohexstr(InputOffset) << " (branch)\n"); - Map.insert(std::pair(OutputOffset, - (InputOffset << 1) | BRANCHENTRY)); + Map.emplace(OutputOffset, (InputOffset << 1) | BRANCHENTRY); } } @@ -108,6 +106,19 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) { for (const BinaryBasicBlock *const BB : Function.getLayout().getMainFragment()) writeEntriesForBB(Map, *BB, InputAddress, OutputAddress); + // Add entries for deleted blocks. They are still required for correct BB + // mapping of branches modified by SCTC. By convention, they would have the + // end of the function as output address. + const BBHashMapTy &BBHashMap = getBBHashMap(InputAddress); + if (BBHashMap.size() != Function.size()) { + const uint64_t EndOffset = Function.getOutputSize(); + std::unordered_set MappedInputOffsets; + for (const BinaryBasicBlock &BB : Function) + MappedInputOffsets.emplace(BB.getInputOffset()); + for (const auto &[InputOffset, _] : BBHashMap) + if (!llvm::is_contained(MappedInputOffsets, InputOffset)) + Map.emplace(EndOffset, InputOffset << 1); + } Maps.emplace(Function.getOutputAddress(), std::move(Map)); ReverseMap.emplace(OutputAddress, InputAddress); @@ -138,8 +149,8 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) { << " basic block hashes\n"; } -APInt BoltAddressTranslation::calculateBranchEntriesBitMask(MapTy &Map, - size_t EqualElems) { +APInt BoltAddressTranslation::calculateBranchEntriesBitMask( + MapTy &Map, size_t EqualElems) const { APInt BitMask(alignTo(EqualElems, 8), 0); size_t Index = 0; for (std::pair &KeyVal : Map) { @@ -422,7 +433,7 @@ void BoltAddressTranslation::parseMaps(std::vector &HotFuncs, } } -void BoltAddressTranslation::dump(raw_ostream &OS) { +void BoltAddressTranslation::dump(raw_ostream &OS) const { const size_t NumTables = Maps.size(); OS << "BAT tables for " << NumTables << " functions:\n"; for (const auto &MapEntry : Maps) { @@ -447,11 +458,15 @@ void BoltAddressTranslation::dump(raw_ostream &OS) { OS << formatv(" hash: {0:x}", BBHashMap.getBBHash(Val)); OS << "\n"; } - if (IsHotFunction) - OS << "NumBlocks: " << NumBasicBlocksMap[Address] << '\n'; - if (SecondaryEntryPointsMap.count(Address)) { + if (IsHotFunction) { + auto NumBasicBlocksIt = NumBasicBlocksMap.find(Address); + assert(NumBasicBlocksIt != NumBasicBlocksMap.end()); + OS << "NumBlocks: " << NumBasicBlocksIt->second << '\n'; + } + auto SecondaryEntryPointsIt = SecondaryEntryPointsMap.find(Address); + if (SecondaryEntryPointsIt != SecondaryEntryPointsMap.end()) { const std::vector &SecondaryEntryPoints = - SecondaryEntryPointsMap[Address]; + SecondaryEntryPointsIt->second; OS << SecondaryEntryPoints.size() << " secondary entry points:\n"; for (uint32_t EntryPointOffset : SecondaryEntryPoints) OS << formatv("{0:x}\n", EntryPointOffset); @@ -547,13 +562,6 @@ BoltAddressTranslation::getFallthroughsInTrace(uint64_t FuncAddress, return Res; } -uint64_t BoltAddressTranslation::fetchParentAddress(uint64_t Address) const { - auto Iter = ColdPartSource.find(Address); - if (Iter == ColdPartSource.end()) - return 0; - return Iter->second; -} - bool BoltAddressTranslation::enabledFor( llvm::object::ELFObjectFileBase *InputFile) const { for (const SectionRef &Section : InputFile->sections()) { diff --git a/bolt/lib/Profile/CMakeLists.txt b/bolt/lib/Profile/CMakeLists.txt index 045ac47edb950..ca8b9c34e63b1 100644 --- a/bolt/lib/Profile/CMakeLists.txt +++ b/bolt/lib/Profile/CMakeLists.txt @@ -17,6 +17,5 @@ add_llvm_library(LLVMBOLTProfile target_link_libraries(LLVMBOLTProfile PRIVATE LLVMBOLTCore - LLVMBOLTPasses LLVMBOLTUtils ) diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp index f55caa7f03f73..ce6ec0a04ac16 100644 --- a/bolt/lib/Profile/DataAggregator.cpp +++ b/bolt/lib/Profile/DataAggregator.cpp @@ -613,7 +613,6 @@ Error DataAggregator::readProfile(BinaryContext &BC) { if (std::error_code EC = writeBATYAML(BC, opts::SaveProfile)) report_error("cannot create output data file", EC); } - BC.logBOLTErrorsAndQuitOnFatal(PrintProgramStats().runOnFunctions(BC)); } return Error::success(); @@ -673,7 +672,8 @@ DataAggregator::getBATParentFunction(const BinaryFunction &Func) const { return nullptr; } -StringRef DataAggregator::getLocationName(const BinaryFunction &Func) const { +StringRef DataAggregator::getLocationName(const BinaryFunction &Func, + bool BAT) { if (!BAT) return Func.getOneName(); @@ -702,7 +702,7 @@ bool DataAggregator::doSample(BinaryFunction &OrigFunc, uint64_t Address, auto I = NamesToSamples.find(Func.getOneName()); if (I == NamesToSamples.end()) { bool Success; - StringRef LocName = getLocationName(Func); + StringRef LocName = getLocationName(Func, BAT); std::tie(I, Success) = NamesToSamples.insert( std::make_pair(Func.getOneName(), FuncSampleData(LocName, FuncSampleData::ContainerTy()))); @@ -722,7 +722,7 @@ bool DataAggregator::doIntraBranch(BinaryFunction &Func, uint64_t From, FuncBranchData *AggrData = getBranchData(Func); if (!AggrData) { AggrData = &NamesToBranches[Func.getOneName()]; - AggrData->Name = getLocationName(Func); + AggrData->Name = getLocationName(Func, BAT); setBranchData(Func, AggrData); } @@ -741,7 +741,7 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc, StringRef SrcFunc; StringRef DstFunc; if (FromFunc) { - SrcFunc = getLocationName(*FromFunc); + SrcFunc = getLocationName(*FromFunc, BAT); FromAggrData = getBranchData(*FromFunc); if (!FromAggrData) { FromAggrData = &NamesToBranches[FromFunc->getOneName()]; @@ -752,7 +752,7 @@ bool DataAggregator::doInterBranch(BinaryFunction *FromFunc, recordExit(*FromFunc, From, Mispreds, Count); } if (ToFunc) { - DstFunc = getLocationName(*ToFunc); + DstFunc = getLocationName(*ToFunc, BAT); ToAggrData = getBranchData(*ToFunc); if (!ToAggrData) { ToAggrData = &NamesToBranches[ToFunc->getOneName()]; @@ -2340,7 +2340,7 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC, continue; BinaryFunction *BF = BC.getBinaryFunctionAtAddress(FuncAddress); assert(BF); - YamlBF.Name = getLocationName(*BF); + YamlBF.Name = getLocationName(*BF, BAT); YamlBF.Id = BF->getFunctionNumber(); YamlBF.Hash = BAT->getBFHash(FuncAddress); YamlBF.ExecCount = BF->getKnownExecutionCount(); @@ -2349,11 +2349,11 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC, BAT->getBBHashMap(FuncAddress); YamlBF.Blocks.resize(YamlBF.NumBasicBlocks); - for (auto &&[Idx, YamlBB] : llvm::enumerate(YamlBF.Blocks)) - YamlBB.Index = Idx; - - for (auto BI = BlockMap.begin(), BE = BlockMap.end(); BI != BE; ++BI) - YamlBF.Blocks[BI->second.getBBIndex()].Hash = BI->second.getBBHash(); + for (auto &&[Entry, YamlBB] : llvm::zip(BlockMap, YamlBF.Blocks)) { + const auto &Block = Entry.second; + YamlBB.Hash = Block.Hash; + YamlBB.Index = Block.Index; + } // Lookup containing basic block offset and index auto getBlock = [&BlockMap](uint32_t Offset) { @@ -2363,7 +2363,7 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC, exit(1); } --BlockIt; - return std::pair(BlockIt->first, BlockIt->second.getBBIndex()); + return std::pair(BlockIt->first, BlockIt->second.Index); }; for (const BranchInfo &BI : Branches.Data) { diff --git a/bolt/lib/Profile/DataReader.cpp b/bolt/lib/Profile/DataReader.cpp index 06c5e96b78064..f2e999bbfdc6d 100644 --- a/bolt/lib/Profile/DataReader.cpp +++ b/bolt/lib/Profile/DataReader.cpp @@ -598,8 +598,6 @@ void DataReader::readSampleData(BinaryFunction &BF) { } BF.ExecutionCount = TotalEntryCount; - - estimateEdgeCounts(BF); } void DataReader::convertBranchData(BinaryFunction &BF) const { diff --git a/bolt/lib/Profile/StaleProfileMatching.cpp b/bolt/lib/Profile/StaleProfileMatching.cpp index 016962ff34d8d..365bc5389266d 100644 --- a/bolt/lib/Profile/StaleProfileMatching.cpp +++ b/bolt/lib/Profile/StaleProfileMatching.cpp @@ -30,6 +30,7 @@ #include "llvm/ADT/Bitfields.h" #include "llvm/ADT/Hashing.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Timer.h" #include "llvm/Support/xxhash.h" #include "llvm/Transforms/Utils/SampleProfileInference.h" @@ -42,6 +43,7 @@ using namespace llvm; namespace opts { +extern cl::opt TimeRewrite; extern cl::OptionCategory BoltOptCategory; cl::opt @@ -372,8 +374,10 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) { // Create necessary metadata for the flow function for (FlowJump &Jump : Func.Jumps) { - Func.Blocks.at(Jump.Source).SuccJumps.push_back(&Jump); - Func.Blocks.at(Jump.Target).PredJumps.push_back(&Jump); + assert(Jump.Source < Func.Blocks.size()); + Func.Blocks[Jump.Source].SuccJumps.push_back(&Jump); + assert(Jump.Target < Func.Blocks.size()); + Func.Blocks[Jump.Target].PredJumps.push_back(&Jump); } return Func; } @@ -705,6 +709,10 @@ void assignProfile(BinaryFunction &BF, bool YAMLProfileReader::inferStaleProfile( BinaryFunction &BF, const yaml::bolt::BinaryFunctionProfile &YamlBF) { + + NamedRegionTimer T("inferStaleProfile", "stale profile inference", "rewrite", + "Rewrite passes", opts::TimeRewrite); + if (!BF.hasCFG()) return false; diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp index 29d94067f459f..f25f59201f1cd 100644 --- a/bolt/lib/Profile/YAMLProfileReader.cpp +++ b/bolt/lib/Profile/YAMLProfileReader.cpp @@ -102,11 +102,14 @@ bool YAMLProfileReader::parseFunctionProfile( if (BF.empty()) return true; - if (!opts::IgnoreHash && - YamlBF.Hash != BF.computeHash(IsDFSOrder, HashFunction)) { - if (opts::Verbosity >= 1) - errs() << "BOLT-WARNING: function hash mismatch\n"; - ProfileMatched = false; + if (!opts::IgnoreHash) { + if (!BF.getHash()) + BF.computeHash(IsDFSOrder, HashFunction); + if (YamlBF.Hash != BF.getHash()) { + if (opts::Verbosity >= 1) + errs() << "BOLT-WARNING: function hash mismatch\n"; + ProfileMatched = false; + } } if (YamlBF.NumBasicBlocks != BF.size()) { @@ -253,10 +256,8 @@ bool YAMLProfileReader::parseFunctionProfile( if (BB.getExecutionCount() == BinaryBasicBlock::COUNT_NO_PROFILE) BB.setExecutionCount(0); - if (YamlBP.Header.Flags & BinaryFunction::PF_SAMPLE) { + if (YamlBP.Header.Flags & BinaryFunction::PF_SAMPLE) BF.setExecutionCount(FunctionExecutionCount); - estimateEdgeCounts(BF); - } ProfileMatched &= !MismatchedBlocks && !MismatchedCalls && !MismatchedEdges; diff --git a/bolt/lib/Profile/YAMLProfileWriter.cpp b/bolt/lib/Profile/YAMLProfileWriter.cpp index ef04ba0d21ad7..cf6b61ddd6031 100644 --- a/bolt/lib/Profile/YAMLProfileWriter.cpp +++ b/bolt/lib/Profile/YAMLProfileWriter.cpp @@ -10,6 +10,7 @@ #include "bolt/Core/BinaryBasicBlock.h" #include "bolt/Core/BinaryFunction.h" #include "bolt/Profile/BoltAddressTranslation.h" +#include "bolt/Profile/DataAggregator.h" #include "bolt/Profile/ProfileReaderBase.h" #include "bolt/Rewrite/RewriteInstance.h" #include "llvm/Support/CommandLine.h" @@ -39,6 +40,10 @@ const BinaryFunction *YAMLProfileWriter::setCSIDestination( BC.getFunctionForSymbol(Symbol, &EntryID)) { if (BAT && BAT->isBATFunction(Callee->getAddress())) std::tie(Callee, EntryID) = BAT->translateSymbol(BC, *Symbol, Offset); + else if (const BinaryBasicBlock *BB = + Callee->getBasicBlockContainingOffset(Offset)) + BC.getFunctionForSymbol(Callee->getSecondaryEntryPointSymbol(*BB), + &EntryID); CSI.DestId = Callee->getFunctionNumber(); CSI.EntryDiscriminator = EntryID; return Callee; @@ -59,7 +64,7 @@ YAMLProfileWriter::convert(const BinaryFunction &BF, bool UseDFS, BF.computeHash(UseDFS); BF.computeBlockHashes(); - YamlBF.Name = BF.getPrintName(); + YamlBF.Name = DataAggregator::getLocationName(BF, BAT); YamlBF.Id = BF.getFunctionNumber(); YamlBF.Hash = BF.getHash(); YamlBF.NumBasicBlocks = BF.size(); diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp index cbb7199a53ddd..aaa0e1ff4d46f 100644 --- a/bolt/lib/Rewrite/BinaryPassManager.cpp +++ b/bolt/lib/Rewrite/BinaryPassManager.cpp @@ -23,6 +23,7 @@ #include "bolt/Passes/JTFootprintReduction.h" #include "bolt/Passes/LongJmp.h" #include "bolt/Passes/LoopInversionPass.h" +#include "bolt/Passes/MCF.h" #include "bolt/Passes/PLTCall.h" #include "bolt/Passes/PatchEntries.h" #include "bolt/Passes/RegReAssign.h" @@ -90,6 +91,11 @@ PrintAfterLowering("print-after-lowering", cl::desc("print function after instruction lowering"), cl::Hidden, cl::cat(BoltOptCategory)); +static cl::opt PrintEstimateEdgeCounts( + "print-estimate-edge-counts", + cl::desc("print function after edge counts are set for no-LBR profile"), + cl::Hidden, cl::cat(BoltOptCategory)); + cl::opt PrintFinalized("print-finalized", cl::desc("print function after CFG is finalized"), @@ -334,8 +340,10 @@ Error BinaryFunctionPassManager::runPasses() { Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) { BinaryFunctionPassManager Manager(BC); - const DynoStats InitialDynoStats = - getDynoStats(BC.getBinaryFunctions(), BC.isAArch64()); + Manager.registerPass( + std::make_unique(PrintEstimateEdgeCounts)); + + Manager.registerPass(std::make_unique()); Manager.registerPass(std::make_unique(), opts::AsmDump.getNumOccurrences()); @@ -447,10 +455,9 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) { Manager.registerPass(std::make_unique(PrintSplit)); // Print final dyno stats right while CFG and instruction analysis are intact. - Manager.registerPass( - std::make_unique( - InitialDynoStats, "after all optimizations before SCTC and FOP"), - opts::PrintDynoStats || opts::DynoStatsAll); + Manager.registerPass(std::make_unique( + "after all optimizations before SCTC and FOP"), + opts::PrintDynoStats || opts::DynoStatsAll); // Add the StokeInfo pass, which extract functions for stoke optimization and // get the liveness information for them diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index d582ce7b33a27..ab46503621e9a 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -73,8 +73,7 @@ static void printDie(DWARFUnit &DU, uint64_t DIEOffset) { DWARFDataExtractor DebugInfoData = DU.getDebugInfoExtractor(); DWARFDebugInfoEntry DIEEntry; if (DIEEntry.extractFast(DU, &DIEOffset, DebugInfoData, NextCUOffset, 0)) { - if (const DWARFAbbreviationDeclaration *AbbrDecl = - DIEEntry.getAbbreviationDeclarationPtr()) { + if (DIEEntry.getAbbreviationDeclarationPtr()) { DWARFDie DDie(&DU, &DIEEntry); printDie(DDie); } else { diff --git a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp index 99775ccfe38d3..b2c8b2446f7e1 100644 --- a/bolt/lib/Rewrite/LinuxKernelRewriter.cpp +++ b/bolt/lib/Rewrite/LinuxKernelRewriter.cpp @@ -393,7 +393,7 @@ void LinuxKernelRewriter::processLKKSymtab(bool IsGPL) { for (uint64_t I = 0; I < SectionSize; I += 4) { const uint64_t EntryAddress = SectionAddress + I; - ErrorOr Offset = BC.getSignedValueAtAddress(EntryAddress, 4); + ErrorOr Offset = BC.getSignedValueAtAddress(EntryAddress, 4); assert(Offset && "Reading valid PC-relative offset for a ksymtab entry"); const int32_t SignedOffset = *Offset; const uint64_t RefAddress = EntryAddress + SignedOffset; diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 6e1021a6df22c..4b4913dd7a16c 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -17,6 +17,7 @@ #include "bolt/Core/MCPlusBuilder.h" #include "bolt/Core/ParallelUtilities.h" #include "bolt/Core/Relocation.h" +#include "bolt/Passes/BinaryPasses.h" #include "bolt/Passes/CacheMetrics.h" #include "bolt/Passes/ReorderFunctions.h" #include "bolt/Profile/BoltAddressTranslation.h" @@ -86,6 +87,7 @@ extern cl::list ReorderData; extern cl::opt ReorderFunctions; extern cl::opt TerminalTrap; extern cl::opt TimeBuild; +extern cl::opt TimeRewrite; cl::opt AllowStripped("allow-stripped", cl::desc("allow processing of stripped binaries"), @@ -235,11 +237,6 @@ UseGnuStack("use-gnu-stack", cl::ZeroOrMore, cl::cat(BoltCategory)); -static cl::opt - TimeRewrite("time-rewrite", - cl::desc("print time spent in rewriting passes"), cl::Hidden, - cl::cat(BoltCategory)); - static cl::opt SequentialDisassembly("sequential-disassembly", cl::desc("performs disassembly sequentially"), @@ -1500,7 +1497,7 @@ void RewriteInstance::registerFragments() { if (!BC->hasSymbolsWithFileName()) { BC->errs() << "BOLT-ERROR: input file has split functions but does not " "have FILE symbols. If the binary was stripped, preserve " - "FILE symbols with --keep-file-symbols strip option"; + "FILE symbols with --keep-file-symbols strip option\n"; exit(1); } @@ -1988,6 +1985,7 @@ Error RewriteInstance::readSpecialSections() { if (ErrorOr BATSec = BC->getUniqueSectionByName(BoltAddressTranslation::SECTION_NAME)) { + BC->HasBATSection = true; // Do not read BAT when plotting a heatmap if (!opts::HeatmapMode) { if (std::error_code EC = BAT->parse(BC->outs(), BATSec->getContents())) { @@ -3208,12 +3206,14 @@ void RewriteInstance::preprocessProfileData() { if (Error E = ProfileReader->preprocessProfile(*BC.get())) report_error("cannot pre-process profile", std::move(E)); - if (!BC->hasSymbolsWithFileName() && ProfileReader->hasLocalsWithFileName()) { + if (!BC->hasSymbolsWithFileName() && ProfileReader->hasLocalsWithFileName() && + !opts::AllowStripped) { BC->errs() << "BOLT-ERROR: input binary does not have local file symbols " "but profile data includes function names with embedded file " "names. It appears that the input binary was stripped while a " - "profiled binary was not\n"; + "profiled binary was not. If you know what you are doing and " + "wish to proceed, use -allow-stripped option.\n"; exit(1); } } @@ -3284,8 +3284,11 @@ void RewriteInstance::processProfileData() { // Release memory used by profile reader. ProfileReader.reset(); - if (opts::AggregateOnly) + if (opts::AggregateOnly) { + PrintProgramStats PPS(&*BAT); + BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*BC)); exit(0); + } } void RewriteInstance::disassembleFunctions() { diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp index 8fdacffcb147b..a33a9dc8c013c 100644 --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -1932,6 +1932,19 @@ class X86MCPlusBuilder : public MCPlusBuilder { // = R_X86_64_PC32(Ln) + En - JT // = R_X86_64_PC32(Ln + offsetof(En)) // + auto isRIPRel = [&](X86MemOperand &MO) { + // NB: DispExpr should be set + return MO.DispExpr != nullptr && + MO.BaseRegNum == RegInfo->getProgramCounter() && + MO.IndexRegNum == X86::NoRegister && + MO.SegRegNum == X86::NoRegister; + }; + auto isIndexed = [](X86MemOperand &MO, MCPhysReg R) { + // NB: IndexRegNum should be set. + return MO.IndexRegNum != X86::NoRegister && MO.BaseRegNum == R && + MO.ScaleImm == 4 && MO.DispImm == 0 && + MO.SegRegNum == X86::NoRegister; + }; LLVM_DEBUG(dbgs() << "Checking for PIC jump table\n"); MCInst *MemLocInstr = nullptr; const MCInst *MovInstr = nullptr; @@ -1965,9 +1978,8 @@ class X86MCPlusBuilder : public MCPlusBuilder { std::optional MO = evaluateX86MemoryOperand(Instr); if (!MO) break; - if (MO->BaseRegNum != R1 || MO->ScaleImm != 4 || - MO->IndexRegNum == X86::NoRegister || MO->DispImm != 0 || - MO->SegRegNum != X86::NoRegister) + if (!isIndexed(*MO, R1)) + // POSSIBLE_PIC_JUMP_TABLE break; MovInstr = &Instr; } else { @@ -1986,9 +1998,7 @@ class X86MCPlusBuilder : public MCPlusBuilder { std::optional MO = evaluateX86MemoryOperand(Instr); if (!MO) break; - if (MO->BaseRegNum != RegInfo->getProgramCounter() || - MO->IndexRegNum != X86::NoRegister || - MO->SegRegNum != X86::NoRegister || MO->DispExpr == nullptr) + if (!isRIPRel(*MO)) break; MemLocInstr = &Instr; break; @@ -2105,13 +2115,15 @@ class X86MCPlusBuilder : public MCPlusBuilder { return IndirectBranchType::POSSIBLE_FIXED_BRANCH; } - if (Type == IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE && - (MO->ScaleImm != 1 || MO->BaseRegNum != RIPRegister)) - return IndirectBranchType::UNKNOWN; - - if (Type != IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE && - MO->ScaleImm != PtrSize) - return IndirectBranchType::UNKNOWN; + switch (Type) { + case IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE: + if (MO->ScaleImm != 1 || MO->BaseRegNum != RIPRegister) + return IndirectBranchType::UNKNOWN; + break; + default: + if (MO->ScaleImm != PtrSize) + return IndirectBranchType::UNKNOWN; + } MemLocInstrOut = MemLocInstr; diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp index ba296c10c00ae..41c89bc8aeba4 100644 --- a/bolt/lib/Utils/CommandLineOpts.cpp +++ b/bolt/lib/Utils/CommandLineOpts.cpp @@ -179,6 +179,10 @@ cl::opt TimeOpts("time-opts", cl::desc("print time spent in each optimization"), cl::cat(BoltOptCategory)); +cl::opt TimeRewrite("time-rewrite", + cl::desc("print time spent in rewriting passes"), + cl::Hidden, cl::cat(BoltCategory)); + cl::opt UseOldText( "use-old-text", cl::desc("re-use space in old .text if possible (relocation mode)"), diff --git a/bolt/runtime/instr.cpp b/bolt/runtime/instr.cpp index 16e0bbd55f90b..d1f8a216badcf 100644 --- a/bolt/runtime/instr.cpp +++ b/bolt/runtime/instr.cpp @@ -1245,7 +1245,6 @@ void Graph::computeEdgeFrequencies(const uint64_t *Counters, continue; assert(SpanningTreeNodes[Cur].NumInEdges == 1, "must have 1 parent"); - const uint32_t Parent = SpanningTreeNodes[Cur].InEdges[0].Node; const uint32_t ParentEdge = SpanningTreeNodes[Cur].InEdges[0].ID; // Calculate parent edge freq. @@ -1464,9 +1463,8 @@ void visitCallFlowEntry(CallFlowHashTable::MapEntry &Entry, int FD, int openProfile() { // Build the profile name string by appending our PID char Buf[BufSize]; - char *Ptr = Buf; uint64_t PID = __getpid(); - Ptr = strCopy(Buf, __bolt_instr_filename, BufSize); + char *Ptr = strCopy(Buf, __bolt_instr_filename, BufSize); if (__bolt_instr_use_pid) { Ptr = strCopy(Ptr, ".", BufSize - (Ptr - Buf + 1)); Ptr = intToStr(Ptr, PID, 10); diff --git a/bolt/test/CMakeLists.txt b/bolt/test/CMakeLists.txt index 89862fd59eb8e..d468ff984840f 100644 --- a/bolt/test/CMakeLists.txt +++ b/bolt/test/CMakeLists.txt @@ -56,7 +56,7 @@ list(APPEND BOLT_TEST_DEPS ) add_custom_target(bolt-test-depends DEPENDS ${BOLT_TEST_DEPS}) -set_target_properties(bolt-test-depends PROPERTIES FOLDER "BOLT") +set_target_properties(bolt-test-depends PROPERTIES FOLDER "BOLT/Tests") add_lit_testsuite(check-bolt "Running the BOLT regression tests" ${CMAKE_CURRENT_BINARY_DIR} @@ -64,7 +64,6 @@ add_lit_testsuite(check-bolt "Running the BOLT regression tests" DEPENDS ${BOLT_TEST_DEPS} ARGS ${BOLT_TEST_EXTRA_ARGS} ) -set_target_properties(check-bolt PROPERTIES FOLDER "BOLT") add_lit_testsuites(BOLT ${CMAKE_CURRENT_SOURCE_DIR} PARAMS ${BOLT_TEST_PARAMS} diff --git a/bolt/test/X86/bb-with-two-tail-calls.s b/bolt/test/X86/bb-with-two-tail-calls.s index b6703e352ff4b..8bbecc498ed75 100644 --- a/bolt/test/X86/bb-with-two-tail-calls.s +++ b/bolt/test/X86/bb-with-two-tail-calls.s @@ -8,11 +8,21 @@ # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib # RUN: llvm-bolt %t.exe -o %t.out --data %t.fdata --lite=0 --dyno-stats \ # RUN: --print-sctc --print-only=_start -enable-bat 2>&1 | FileCheck %s +# RUN: llvm-objdump --syms %t.out > %t.log +# RUN: llvm-bat-dump %t.out --dump-all >> %t.log +# RUN: FileCheck %s --input-file %t.log --check-prefix=CHECK-BAT + # CHECK-NOT: Assertion `BranchInfo.size() == 2 && "could only be called for blocks with 2 successors"' failed. # Two tail calls in the same basic block after SCTC: # CHECK: {{.*}}: ja {{.*}} # TAILCALL # Offset: 7 # CTCTakenCount: 4 # CHECK-NEXT: {{.*}}: jmp {{.*}} # TAILCALL # Offset: 13 +# Confirm that a deleted basic block is emitted at function end offset (0xe) +# CHECK-BAT: [[#%x,ADDR:]] g .text [[#%x,SIZE:]] _start +# CHECK-BAT: Function Address: 0x[[#%x,ADDR]] +# CHECK-BAT: 0x[[#%x,SIZE]] +# CHECK-BAT: NumBlocks: 5 + .globl _start _start: je x diff --git a/bolt/test/X86/bolt-address-translation-yaml.test b/bolt/test/X86/bolt-address-translation-yaml.test index e21513b7dfe59..8f65eaba891ec 100644 --- a/bolt/test/X86/bolt-address-translation-yaml.test +++ b/bolt/test/X86/bolt-address-translation-yaml.test @@ -31,7 +31,8 @@ RUN: perf2bolt %t.out --pa -p %p/Inputs/blarge_new_bat.preagg.txt -w %t.yaml -o RUN: 2>&1 | FileCheck --check-prefix READ-BAT-CHECK %s RUN: FileCheck --input-file %t.yaml --check-prefix YAML-BAT-CHECK %s # Check that YAML converted from fdata matches YAML created directly with BAT. -RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o /dev/null +RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o /dev/null \ +RUN: 2>&1 | FileCheck --check-prefix READ-BAT-FDATA-CHECK %s RUN: FileCheck --input-file %t.yaml-fdata --check-prefix YAML-BAT-CHECK %s # Test resulting YAML profile with the original binary (no-stale mode) @@ -40,11 +41,13 @@ RUN: | FileCheck --check-prefix CHECK-BOLT-YAML %s WRITE-BAT-CHECK: BOLT-INFO: Wrote 5 BAT maps WRITE-BAT-CHECK: BOLT-INFO: Wrote 4 function and 22 basic block hashes -WRITE-BAT-CHECK: BOLT-INFO: BAT section size (bytes): 384 +WRITE-BAT-CHECK: BOLT-INFO: BAT section size (bytes): 404 READ-BAT-CHECK-NOT: BOLT-ERROR: unable to save profile in YAML format for input file processed by BOLT READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries READ-BAT-CHECK: PERF2BOLT: read 79 aggregated LBR entries +READ-BAT-CHECK: BOLT-INFO: 5 out of 21 functions in the binary (23.8%) have non-empty execution profile +READ-BAT-FDATA-CHECK: BOLT-INFO: 5 out of 16 functions in the binary (31.2%) have non-empty execution profile YAML-BAT-CHECK: functions: # Function not covered by BAT - has insns in basic block diff --git a/bolt/test/X86/bolt-address-translation.test b/bolt/test/X86/bolt-address-translation.test index e6b21c14077b4..dfdd1eea32333 100644 --- a/bolt/test/X86/bolt-address-translation.test +++ b/bolt/test/X86/bolt-address-translation.test @@ -37,7 +37,7 @@ # CHECK: BOLT: 3 out of 7 functions were overwritten. # CHECK: BOLT-INFO: Wrote 6 BAT maps # CHECK: BOLT-INFO: Wrote 3 function and 58 basic block hashes -# CHECK: BOLT-INFO: BAT section size (bytes): 928 +# CHECK: BOLT-INFO: BAT section size (bytes): 940 # # usqrt mappings (hot part). We match against any key (left side containing # the bolted binary offsets) because BOLT may change where it puts instructions diff --git a/bolt/test/X86/dwarf5-debug-names-class-type-decl.s b/bolt/test/X86/dwarf5-debug-names-class-type-decl.s new file mode 100644 index 0000000000000..587eaaf6f4ffa --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-class-type-decl.s @@ -0,0 +1,670 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o +# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt > %t.txt +# RUN: llvm-dwarfdump --show-form --verbose --debug-names %t.bolt >> %t.txt +# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s + +## This tests that BOLT doesn't generate entry for a DW_TAG_class_type declaration with DW_AT_name. + +# POSTCHECK: DW_TAG_type_unit +# POSTCHECK: DW_TAG_class_type [7] +# POSTCHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (00000006) string = "InnerState") +# POSTCHECK-NEXT: DW_AT_declaration [DW_FORM_flag_present] (true) +# POSTCHECK: Name Index +# POSTCHECK-NOT: "InnerState" + +## -g2 -O0 -fdebug-types-section -gpubnames +## namespace A { +## namespace B { +## class State { +## public: +## class InnerState{ +## InnerState() {} +## }; +## State(){} +## State(InnerState S){} +## }; +## } +## } +## +## int main() { +## A::B::State S; +## return 0; +## } + + .text + .file "main.cpp" + .file 0 "/DW_TAG_class_type" "main.cpp" md5 0x80f261b124b76c481b8761c040ab4802 + .section .debug_info,"G",@progbits,16664150534606561860,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad -1782593539102989756 # Type Signature + .long 39 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x3b DW_TAG_type_unit + .short 33 # DW_AT_language + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x23:0x2a DW_TAG_namespace + .byte 3 # DW_AT_name + .byte 2 # Abbrev [2] 0x25:0x27 DW_TAG_namespace + .byte 4 # DW_AT_name + .byte 3 # Abbrev [3] 0x27:0x24 DW_TAG_class_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 4 # Abbrev [4] 0x2d:0xb DW_TAG_subprogram + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 5 # Abbrev [5] 0x32:0x5 DW_TAG_formal_parameter + .long 77 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x38:0x10 DW_TAG_subprogram + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 5 # Abbrev [5] 0x3d:0x5 DW_TAG_formal_parameter + .long 77 # DW_AT_type + # DW_AT_artificial + .byte 6 # Abbrev [6] 0x42:0x5 DW_TAG_formal_parameter + .long 72 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x48:0x2 DW_TAG_class_type + .byte 6 # DW_AT_name + # DW_AT_declaration + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x4d:0x5 DW_TAG_pointer_type + .long 39 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .loc 0 14 0 # main.cpp:14:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $16, %rsp + movl $0, -4(%rbp) +.Ltmp0: + .loc 0 15 15 prologue_end # main.cpp:15:15 + leaq -5(%rbp), %rdi + callq _ZN1A1B5StateC2Ev + .loc 0 16 3 # main.cpp:16:3 + xorl %eax, %eax + .loc 0 16 3 epilogue_begin is_stmt 0 # main.cpp:16:3 + addq $16, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .text._ZN1A1B5StateC2Ev,"axG",@progbits,_ZN1A1B5StateC2Ev,comdat + .weak _ZN1A1B5StateC2Ev # -- Begin function _ZN1A1B5StateC2Ev + .p2align 4, 0x90 + .type _ZN1A1B5StateC2Ev,@function +_ZN1A1B5StateC2Ev: # @_ZN1A1B5StateC2Ev +.Lfunc_begin1: + .loc 0 8 0 is_stmt 1 # main.cpp:8:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rdi, -8(%rbp) +.Ltmp2: + .loc 0 8 15 prologue_end epilogue_begin # main.cpp:8:15 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _ZN1A1B5StateC2Ev, .Lfunc_end1-_ZN1A1B5StateC2Ev + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 50 # DW_AT_accessibility + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 52 # DW_AT_artificial + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 35 # DW_FORM_rnglistx + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 116 # DW_AT_rnglists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 1 # DW_CHILDREN_yes + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 12 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 13 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 100 # DW_AT_object_pointer + .byte 19 # DW_FORM_ref4 + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 14 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 52 # DW_AT_artificial + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 15 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 9 # Abbrev [9] 0xc:0x7f DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .byte 0 # DW_AT_ranges + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lrnglists_table_base0 # DW_AT_rnglists_base + .byte 2 # Abbrev [2] 0x2b:0x1b DW_TAG_namespace + .byte 3 # DW_AT_name + .byte 2 # Abbrev [2] 0x2d:0x18 DW_TAG_namespace + .byte 4 # DW_AT_name + .byte 10 # Abbrev [10] 0x2f:0x15 DW_TAG_class_type + # DW_AT_declaration + .quad -1782593539102989756 # DW_AT_signature + .byte 4 # Abbrev [4] 0x38:0xb DW_TAG_subprogram + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 5 # Abbrev [5] 0x3d:0x5 DW_TAG_formal_parameter + .long 97 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 11 # Abbrev [11] 0x46:0x1b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 129 # DW_AT_type + # DW_AT_external + .byte 12 # Abbrev [12] 0x55:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 123 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 15 # DW_AT_decl_line + .long 47 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x61:0x5 DW_TAG_pointer_type + .long 47 # DW_AT_type + .byte 13 # Abbrev [13] 0x66:0x1b DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 119 # DW_AT_object_pointer + .byte 9 # DW_AT_linkage_name + .long 56 # DW_AT_specification + .byte 14 # Abbrev [14] 0x77:0x9 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 11 # DW_AT_name + .long 133 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 15 # Abbrev [15] 0x81:0x4 DW_TAG_base_type + .byte 8 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 8 # Abbrev [8] 0x85:0x5 DW_TAG_pointer_type + .long 47 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_rnglists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 1 # Offset entry count +.Lrnglists_table_base0: + .long .Ldebug_ranges0-.Lrnglists_table_base0 +.Ldebug_ranges0: + .byte 3 # DW_RLE_startx_length + .byte 0 # start index + .uleb128 .Lfunc_end0-.Lfunc_begin0 # length + .byte 3 # DW_RLE_startx_length + .byte 1 # start index + .uleb128 .Lfunc_end1-.Lfunc_begin1 # length + .byte 0 # DW_RLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_str_offsets,"",@progbits + .long 52 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "/home/ayermolo/local/tasks/T190087639/DW_TAG_class_type" # string offset=33 +.Linfo_string3: + .asciz "A" # string offset=89 +.Linfo_string4: + .asciz "B" # string offset=91 +.Linfo_string5: + .asciz "State" # string offset=93 +.Linfo_string6: + .asciz "InnerState" # string offset=99 +.Linfo_string7: + .asciz "main" # string offset=110 +.Linfo_string8: + .asciz "_ZN1A1B5StateC2Ev" # string offset=115 +.Linfo_string9: + .asciz "int" # string offset=133 +.Linfo_string10: + .asciz "S" # string offset=137 +.Linfo_string11: + .asciz "this" # string offset=139 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string9 + .long .Linfo_string8 + .long .Linfo_string10 + .long .Linfo_string11 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 1 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Ltu_begin0 # Type unit 0 + .long 0 # Bucket 0 + .long 0 # Bucket 1 + .long 1 # Bucket 2 + .long 2 # Bucket 3 + .long 3 # Bucket 4 + .long 6 # Bucket 5 + .long 193495088 # Hash in Bucket 2 + .long 1059643959 # Hash in Bucket 3 + .long 177670 # Hash in Bucket 4 + .long 274811398 # Hash in Bucket 4 + .long 2090499946 # Hash in Bucket 4 + .long 177671 # Hash in Bucket 5 + .long .Linfo_string9 # String in Bucket 2: int + .long .Linfo_string8 # String in Bucket 3: _ZN1A1B5StateC2Ev + .long .Linfo_string3 # String in Bucket 4: A + .long .Linfo_string5 # String in Bucket 4: State + .long .Linfo_string7 # String in Bucket 4: main + .long .Linfo_string4 # String in Bucket 5: B + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 2 # DW_TAG_class_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 6 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 7 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames5: +.L2: + .byte 1 # Abbreviation code + .long 129 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames4: +.L3: + .byte 2 # Abbreviation code + .long 102 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN1A1B5StateC2Ev +.Lnames0: +.L4: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L7: # DW_IDX_parent + .byte 4 # Abbreviation code + .long 43 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: A +.Lnames2: +.L1: + .byte 5 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 39 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent + .byte 2 # Abbreviation code + .long 102 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: State +.Lnames3: +.L0: + .byte 2 # Abbreviation code + .long 70 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L5: + .byte 6 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 37 # DW_IDX_die_offset + .long .L4-.Lnames_entries0 # DW_IDX_parent +.L6: + .byte 7 # Abbreviation code + .long 45 # DW_IDX_die_offset + .long .L7-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: B + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-enumeration-type-decl.s b/bolt/test/X86/dwarf5-debug-names-enumeration-type-decl.s new file mode 100644 index 0000000000000..031175763d794 --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-enumeration-type-decl.s @@ -0,0 +1,485 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o +# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt > %t.txt +# RUN: llvm-dwarfdump --show-form --verbose --debug-names %t.bolt >> %t.txt +# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s + +## This tests that BOLT doesn't generate entry for a DW_TAG_enumeration_type declaration with DW_AT_name. + +# POSTCHECK: DW_TAG_type_unit +# POSTCHECK: DW_TAG_enumeration_type [6] +# POSTCHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (00000009) string = "InnerState") +# POSTCHECK-NEXT: DW_AT_byte_size [DW_FORM_data1] (0x04) +# POSTCHECK-NEXT: DW_AT_declaration [DW_FORM_flag_present] (true) +# POSTCHECK: Name Index +# POSTCHECK-NOT: "InnerState" + +## -g2 -O0 -fdebug-types-section -gpubnames +## namespace B { +## template +## class State { +## public: +## enum class InnerState { STATE0 }; +## InnerState St; +## }; +## } +## +## int main() { +## B::State S; +## return 0; +## } + + .text + .file "main.cpp" + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .file 0 "/DW_TAG_enumeration_type" "main.cpp" md5 0x2e8962f8ef4bf6eb6f8bd92966c0848b + .loc 0 10 0 # main.cpp:10:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl $0, -4(%rbp) +.Ltmp0: + .loc 0 12 3 prologue_end # main.cpp:12:3 + xorl %eax, %eax + .loc 0 12 3 epilogue_begin is_stmt 0 # main.cpp:12:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .debug_info,"G",@progbits,8822129917070965541,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad 8822129917070965541 # Type Signature + .long 37 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x2d DW_TAG_type_unit + .short 33 # DW_AT_language + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x23:0x1d DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 3 # Abbrev [3] 0x25:0x1a DW_TAG_class_type + .byte 5 # DW_AT_calling_convention + .byte 10 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 4 # Abbrev [4] 0x2b:0x6 DW_TAG_template_type_parameter + .long 64 # DW_AT_type + .byte 7 # DW_AT_name + .byte 5 # Abbrev [5] 0x31:0xa DW_TAG_member + .byte 8 # DW_AT_name + .long 59 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 6 # Abbrev [6] 0x3b:0x3 DW_TAG_enumeration_type + .byte 9 # DW_AT_name + .byte 4 # DW_AT_byte_size + # DW_AT_declaration + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x40:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 47 # DW_TAG_template_type_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 13 # DW_TAG_member + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 56 # DW_AT_data_member_location + .byte 11 # DW_FORM_data1 + .byte 50 # DW_AT_accessibility + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 4 # DW_TAG_enumeration_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 0 # DW_CHILDREN_no + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Abbrev [8] 0xc:0x43 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 9 # Abbrev [9] 0x23:0x1b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 10 # DW_AT_decl_line + .long 62 # DW_AT_type + # DW_AT_external + .byte 10 # Abbrev [10] 0x32:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 11 # DW_AT_decl_line + .long 68 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x3e:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 2 # Abbrev [2] 0x42:0xc DW_TAG_namespace + .byte 6 # DW_AT_name + .byte 11 # Abbrev [11] 0x44:0x9 DW_TAG_class_type + # DW_AT_declaration + .quad 8822129917070965541 # DW_AT_signature + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "/home/ayermolo/local/tasks/T190087639/DW_TAG_enumeration_type" # string offset=33 +.Linfo_string3: + .asciz "main" # string offset=95 +.Linfo_string4: + .asciz "int" # string offset=100 +.Linfo_string5: + .asciz "S" # string offset=104 +.Linfo_string6: + .asciz "B" # string offset=106 +.Linfo_string7: + .asciz "Task" # string offset=108 +.Linfo_string8: + .asciz "St" # string offset=113 +.Linfo_string9: + .asciz "InnerState" # string offset=116 +.Linfo_string10: + .asciz "State" # string offset=127 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 1 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 4 # Header: bucket count + .long 4 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Ltu_begin0 # Type unit 0 + .long 1 # Bucket 0 + .long 0 # Bucket 1 + .long 2 # Bucket 2 + .long 3 # Bucket 3 + .long 193495088 # Hash in Bucket 0 + .long 2090499946 # Hash in Bucket 2 + .long 177671 # Hash in Bucket 3 + .long 624407275 # Hash in Bucket 3 + .long .Linfo_string4 # String in Bucket 0: int + .long .Linfo_string3 # String in Bucket 2: main + .long .Linfo_string6 # String in Bucket 3: B + .long .Linfo_string10 # String in Bucket 3: State + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 3 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 6 # Abbrev code + .byte 2 # DW_TAG_class_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L0: + .byte 1 # Abbreviation code + .long 62 # DW_IDX_die_offset +.L2: # DW_IDX_parent + .byte 2 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 64 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames0: +.L3: + .byte 3 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames2: + .byte 4 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L1: # DW_IDX_parent + .byte 5 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: B +.Lnames3: +.L4: + .byte 6 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 37 # DW_IDX_die_offset + .long .L3-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: State + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-structure-type-decl.s b/bolt/test/X86/dwarf5-debug-names-structure-type-decl.s new file mode 100644 index 0000000000000..6eb2852c26ba0 --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-structure-type-decl.s @@ -0,0 +1,671 @@ +# REQUIRES: system-linux + +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o +# RUN: %clang %cflags -dwarf-5 %t1.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections +# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt > %t.txt +# RUN: llvm-dwarfdump --show-form --verbose --debug-names %t.bolt >> %t.txt +# RUN: cat %t.txt | FileCheck --check-prefix=POSTCHECK %s + +## This tests that BOLT doesn't generate entry for a DW_TAG_structure_type declaration with DW_AT_name. + +# POSTCHECK: DW_TAG_type_unit +# POSTCHECK: DW_TAG_structure_type [7] +# POSTCHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (00000006) string = "InnerState") +# POSTCHECK-NEXT: DW_AT_declaration [DW_FORM_flag_present] (true) +# POSTCHECK: Name Index +# POSTCHECK-NOT: "InnerState" + +## -g2 -O0 -fdebug-types-section -gpubnames +## namespace A { +## namespace B { +## class State { +## public: +## struct InnerState{ +## InnerState() {} +## }; +## State(){} +## State(InnerState S){} +## }; +## } +## } +## +## int main() { +## A::B::State S; +## return 0; +## } + + + .text + .file "main.cpp" + .file 0 "/DW_TAG_structure_type" "main.cpp" md5 0xd43ba503b70d00353c195087e1fe16e2 + .section .debug_info,"G",@progbits,16664150534606561860,comdat +.Ltu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 2 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .quad -1782593539102989756 # Type Signature + .long 39 # Type DIE Offset + .byte 1 # Abbrev [1] 0x18:0x3b DW_TAG_type_unit + .short 33 # DW_AT_language + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .byte 2 # Abbrev [2] 0x23:0x2a DW_TAG_namespace + .byte 3 # DW_AT_name + .byte 2 # Abbrev [2] 0x25:0x27 DW_TAG_namespace + .byte 4 # DW_AT_name + .byte 3 # Abbrev [3] 0x27:0x24 DW_TAG_class_type + .byte 5 # DW_AT_calling_convention + .byte 5 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 4 # Abbrev [4] 0x2d:0xb DW_TAG_subprogram + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 5 # Abbrev [5] 0x32:0x5 DW_TAG_formal_parameter + .long 77 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x38:0x10 DW_TAG_subprogram + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 5 # Abbrev [5] 0x3d:0x5 DW_TAG_formal_parameter + .long 77 # DW_AT_type + # DW_AT_artificial + .byte 6 # Abbrev [6] 0x42:0x5 DW_TAG_formal_parameter + .long 72 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x48:0x2 DW_TAG_structure_type + .byte 6 # DW_AT_name + # DW_AT_declaration + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x4d:0x5 DW_TAG_pointer_type + .long 39 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .text + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .loc 0 14 0 # main.cpp:14:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + subq $16, %rsp + movl $0, -4(%rbp) +.Ltmp0: + .loc 0 15 15 prologue_end # main.cpp:15:15 + leaq -5(%rbp), %rdi + callq _ZN1A1B5StateC2Ev + .loc 0 16 3 # main.cpp:16:3 + xorl %eax, %eax + .loc 0 16 3 epilogue_begin is_stmt 0 # main.cpp:16:3 + addq $16, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section .text._ZN1A1B5StateC2Ev,"axG",@progbits,_ZN1A1B5StateC2Ev,comdat + .weak _ZN1A1B5StateC2Ev # -- Begin function _ZN1A1B5StateC2Ev + .p2align 4, 0x90 + .type _ZN1A1B5StateC2Ev,@function +_ZN1A1B5StateC2Ev: # @_ZN1A1B5StateC2Ev +.Lfunc_begin1: + .loc 0 8 0 is_stmt 1 # main.cpp:8:0 + .cfi_startproc +# %bb.0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rdi, -8(%rbp) +.Ltmp2: + .loc 0 8 15 prologue_end epilogue_begin # main.cpp:8:15 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp3: +.Lfunc_end1: + .size _ZN1A1B5StateC2Ev, .Lfunc_end1-_ZN1A1B5StateC2Ev + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 65 # DW_TAG_type_unit + .byte 1 # DW_CHILDREN_yes + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 57 # DW_TAG_namespace + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 50 # DW_AT_accessibility + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 52 # DW_AT_artificial + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 35 # DW_FORM_rnglistx + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 116 # DW_AT_rnglists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 1 # DW_CHILDREN_yes + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 105 # DW_AT_signature + .byte 32 # DW_FORM_ref_sig8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 12 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 13 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 100 # DW_AT_object_pointer + .byte 19 # DW_FORM_ref4 + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 14 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 52 # DW_AT_artificial + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 15 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit +.Ldebug_info_start1: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 9 # Abbrev [9] 0xc:0x7f DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .byte 0 # DW_AT_ranges + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lrnglists_table_base0 # DW_AT_rnglists_base + .byte 2 # Abbrev [2] 0x2b:0x1b DW_TAG_namespace + .byte 3 # DW_AT_name + .byte 2 # Abbrev [2] 0x2d:0x18 DW_TAG_namespace + .byte 4 # DW_AT_name + .byte 10 # Abbrev [10] 0x2f:0x15 DW_TAG_class_type + # DW_AT_declaration + .quad -1782593539102989756 # DW_AT_signature + .byte 4 # Abbrev [4] 0x38:0xb DW_TAG_subprogram + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 5 # Abbrev [5] 0x3d:0x5 DW_TAG_formal_parameter + .long 97 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 11 # Abbrev [11] 0x46:0x1b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 129 # DW_AT_type + # DW_AT_external + .byte 12 # Abbrev [12] 0x55:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 123 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 15 # DW_AT_decl_line + .long 47 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 8 # Abbrev [8] 0x61:0x5 DW_TAG_pointer_type + .long 47 # DW_AT_type + .byte 13 # Abbrev [13] 0x66:0x1b DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 119 # DW_AT_object_pointer + .byte 9 # DW_AT_linkage_name + .long 56 # DW_AT_specification + .byte 14 # Abbrev [14] 0x77:0x9 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 11 # DW_AT_name + .long 133 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 15 # Abbrev [15] 0x81:0x4 DW_TAG_base_type + .byte 8 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 8 # Abbrev [8] 0x85:0x5 DW_TAG_pointer_type + .long 47 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end1: + .section .debug_rnglists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 1 # Offset entry count +.Lrnglists_table_base0: + .long .Ldebug_ranges0-.Lrnglists_table_base0 +.Ldebug_ranges0: + .byte 3 # DW_RLE_startx_length + .byte 0 # start index + .uleb128 .Lfunc_end0-.Lfunc_begin0 # length + .byte 3 # DW_RLE_startx_length + .byte 1 # start index + .uleb128 .Lfunc_end1-.Lfunc_begin1 # length + .byte 0 # DW_RLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_str_offsets,"",@progbits + .long 52 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 19.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "/home/ayermolo/local/tasks/T190087639/DW_TAG_structure_type" # string offset=33 +.Linfo_string3: + .asciz "A" # string offset=93 +.Linfo_string4: + .asciz "B" # string offset=95 +.Linfo_string5: + .asciz "State" # string offset=97 +.Linfo_string6: + .asciz "InnerState" # string offset=103 +.Linfo_string7: + .asciz "main" # string offset=114 +.Linfo_string8: + .asciz "_ZN1A1B5StateC2Ev" # string offset=119 +.Linfo_string9: + .asciz "int" # string offset=137 +.Linfo_string10: + .asciz "S" # string offset=141 +.Linfo_string11: + .asciz "this" # string offset=143 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string9 + .long .Linfo_string8 + .long .Linfo_string10 + .long .Linfo_string11 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 1 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 6 # Header: bucket count + .long 6 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long .Ltu_begin0 # Type unit 0 + .long 0 # Bucket 0 + .long 0 # Bucket 1 + .long 1 # Bucket 2 + .long 2 # Bucket 3 + .long 3 # Bucket 4 + .long 6 # Bucket 5 + .long 193495088 # Hash in Bucket 2 + .long 1059643959 # Hash in Bucket 3 + .long 177670 # Hash in Bucket 4 + .long 274811398 # Hash in Bucket 4 + .long 2090499946 # Hash in Bucket 4 + .long 177671 # Hash in Bucket 5 + .long .Linfo_string9 # String in Bucket 2: int + .long .Linfo_string8 # String in Bucket 3: _ZN1A1B5StateC2Ev + .long .Linfo_string3 # String in Bucket 4: A + .long .Linfo_string5 # String in Bucket 4: State + .long .Linfo_string7 # String in Bucket 4: main + .long .Linfo_string4 # String in Bucket 5: B + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 2 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 5 # Abbrev code + .byte 2 # DW_TAG_class_type + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 6 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 2 # DW_IDX_type_unit + .byte 11 # DW_FORM_data1 + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 7 # Abbrev code + .byte 57 # DW_TAG_namespace + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames5: +.L2: + .byte 1 # Abbreviation code + .long 129 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames4: +.L3: + .byte 2 # Abbreviation code + .long 102 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN1A1B5StateC2Ev +.Lnames0: +.L4: + .byte 3 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 35 # DW_IDX_die_offset +.L7: # DW_IDX_parent + .byte 4 # Abbreviation code + .long 43 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: A +.Lnames2: +.L1: + .byte 5 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 39 # DW_IDX_die_offset + .long .L5-.Lnames_entries0 # DW_IDX_parent + .byte 2 # Abbreviation code + .long 102 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: State +.Lnames3: +.L0: + .byte 2 # Abbreviation code + .long 70 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L5: + .byte 6 # Abbreviation code + .byte 0 # DW_IDX_type_unit + .long 37 # DW_IDX_die_offset + .long .L4-.Lnames_entries0 # DW_IDX_parent +.L6: + .byte 7 # Abbreviation code + .long 45 # DW_IDX_die_offset + .long .L7-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: B + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 19.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/ignored-interprocedural-reference.s b/bolt/test/X86/ignored-interprocedural-reference.s new file mode 100644 index 0000000000000..12e4fb92adcc0 --- /dev/null +++ b/bolt/test/X86/ignored-interprocedural-reference.s @@ -0,0 +1,49 @@ +# This reproduces a bug with not processing interprocedural references from +# ignored functions. + +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags %t.o -o %t.exe -nostdlib -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.out --enable-bat -funcs=main +# RUN: link_fdata %s %t.out %t.preagg PREAGG +# RUN: perf2bolt %t.out -p %t.preagg --pa -o %t.fdata -w %t.yaml +# RUN: FileCheck %s --input-file=%t.fdata --check-prefix=CHECK-FDATA +# RUN: FileCheck %s --input-file=%t.yaml --check-prefix=CHECK-YAML + +# CHECK-FDATA: 1 main 0 1 foo a 1 1 +# CHECK-YAML: name: main +# CHECK-YAML: calls: {{.*}} disc: 1 + +# PREAGG: B #main# #foo_secondary# 1 1 +# main calls foo at valid instruction offset past nops that are to be stripped. + .globl main +main: + .cfi_startproc + call foo_secondary + ret + .cfi_endproc +.size main,.-main + +# Placeholder cold fragment to force main to be ignored in non-relocation mode. + .globl main.cold +main.cold: + .cfi_startproc + ud2 + .cfi_endproc +.size main.cold,.-main.cold + +# foo is set up to contain a valid instruction at called offset, and trapping +# instructions past that. + .globl foo +foo: + .cfi_startproc + .nops 10 + .globl foo_secondary +foo_secondary: + ret + .rept 20 + int3 + .endr + .cfi_endproc +.size foo,.-foo diff --git a/bolt/test/X86/register-fragments-bolt-symbols.s b/bolt/test/X86/register-fragments-bolt-symbols.s index 6478adf19372b..90c402b2234d7 100644 --- a/bolt/test/X86/register-fragments-bolt-symbols.s +++ b/bolt/test/X86/register-fragments-bolt-symbols.s @@ -18,6 +18,11 @@ # RUN: FileCheck --input-file %t.bat.fdata --check-prefix=CHECK-FDATA %s # RUN: FileCheck --input-file %t.bat.yaml --check-prefix=CHECK-YAML %s +# RUN: link_fdata --no-redefine %s %t.bolt %t.preagg2 PREAGG2 +# PREAGG2: B X:0 #chain# 1 0 +# RUN: perf2bolt %t.bolt -p %t.preagg2 --pa -o %t.bat2.fdata -w %t.bat2.yaml +# RUN: FileCheck %s --input-file %t.bat2.yaml --check-prefix=CHECK-YAML2 + # CHECK-SYMS: l df *ABS* [[#]] chain.s # CHECK-SYMS: l F .bolt.org.text [[#]] chain # CHECK-SYMS: l F .text.cold [[#]] chain.cold.0 @@ -28,6 +33,9 @@ # CHECK-FDATA: 0 [unknown] 0 1 chain/chain.s/2 10 0 1 # CHECK-YAML: - name: 'chain/chain.s/2' +# CHECK-YAML2: - name: 'chain/chain.s/1' +## non-BAT function has non-zero insns: +# CHECK-YAML2: insns: 1 .file "chain.s" .text diff --git a/bolt/test/link_fdata.py b/bolt/test/link_fdata.py index 0232dd3211e9b..3837e394ccc87 100755 --- a/bolt/test/link_fdata.py +++ b/bolt/test/link_fdata.py @@ -19,6 +19,7 @@ parser.add_argument("prefix", nargs="?", default="FDATA", help="Custom FDATA prefix") parser.add_argument("--nmtool", default="nm", help="Path to nm tool") parser.add_argument("--no-lbr", action="store_true") +parser.add_argument("--no-redefine", action="store_true") args = parser.parse_args() @@ -90,6 +91,8 @@ symbols = {} for symline in nm_output.splitlines(): symval, _, symname = symline.split(maxsplit=2) + if symname in symbols and args.no_redefine: + continue symbols[symname] = symval diff --git a/bolt/unittests/CMakeLists.txt b/bolt/unittests/CMakeLists.txt index 77159e92dec55..64414b83d39fe 100644 --- a/bolt/unittests/CMakeLists.txt +++ b/bolt/unittests/CMakeLists.txt @@ -1,5 +1,5 @@ add_custom_target(BoltUnitTests) -set_target_properties(BoltUnitTests PROPERTIES FOLDER "BOLT tests") +set_target_properties(BoltUnitTests PROPERTIES FOLDER "BOLT/Tests") function(add_bolt_unittest test_dirname) add_unittest(BoltUnitTests ${test_dirname} ${ARGN}) diff --git a/clang-tools-extra/CMakeLists.txt b/clang-tools-extra/CMakeLists.txt index 6a3f741721ee6..f6a6b57b5ef0b 100644 --- a/clang-tools-extra/CMakeLists.txt +++ b/clang-tools-extra/CMakeLists.txt @@ -1,3 +1,5 @@ +set(LLVM_SUBPROJECT_TITLE "Clang Tools Extra") + include(CMakeDependentOption) include(GNUInstallDirs) diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt index 7e1905aa897b7..430ea4cdbb38e 100644 --- a/clang-tools-extra/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/CMakeLists.txt @@ -121,7 +121,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) PATTERN "*.h" ) add_custom_target(clang-tidy-headers) - set_target_properties(clang-tidy-headers PROPERTIES FOLDER "Misc") + set_target_properties(clang-tidy-headers PROPERTIES FOLDER "Clang Tools Extra/Resources") if(NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-clang-tidy-headers DEPENDS clang-tidy-headers diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp index 36687a8e761e8..c87b3ea7e2616 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp @@ -54,7 +54,9 @@ AST_MATCHER(QualType, isEnableIf) { AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument, clang::ast_matchers::internal::Matcher, TypeMatcher) { return Node.hasDefaultArgument() && - TypeMatcher.matches(Node.getDefaultArgument(), Finder, Builder); + TypeMatcher.matches( + Node.getDefaultArgument().getArgument().getAsType(), Finder, + Builder); } AST_MATCHER(TemplateDecl, hasAssociatedConstraints) { return Node.hasAssociatedConstraints(); diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp index 09aaf3e31d5dd..75f1107904fce 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp @@ -19,10 +19,11 @@ namespace { AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument, ast_matchers::internal::Matcher, InnerMatcher) { if (Node.getIdentifier() != nullptr || !Node.hasDefaultArgument() || - Node.getDefaultArgumentInfo() == nullptr) + Node.getDefaultArgument().getArgument().isNull()) return false; - TypeLoc DefaultArgTypeLoc = Node.getDefaultArgumentInfo()->getTypeLoc(); + TypeLoc DefaultArgTypeLoc = + Node.getDefaultArgument().getTypeSourceInfo()->getTypeLoc(); return InnerMatcher.matches(DefaultArgTypeLoc, Finder, Builder); } diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp index a1cffbc666199..5e64d23874ec1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -144,16 +144,13 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { unaryOperator(hasUnaryOperand(ArrayExpr), unless(hasOperatorName("*"))), binaryOperator(hasEitherOperand(ArrayExpr)), castExpr(hasSourceExpression(ArrayExpr)))); - const auto PointerToArrayExpr = ignoringParenImpCasts( - hasType(hasCanonicalType(pointerType(pointee(arrayType()))))); + const auto PointerToArrayExpr = + hasType(hasCanonicalType(pointerType(pointee(arrayType())))); - const auto StructAddrOfExpr = unaryOperator( - hasOperatorName("&"), hasUnaryOperand(ignoringParenImpCasts( - hasType(hasCanonicalType(recordType()))))); const auto PointerToStructType = hasUnqualifiedDesugaredType(pointerType(pointee(recordType()))); - const auto PointerToStructExpr = ignoringParenImpCasts(expr( - hasType(hasCanonicalType(PointerToStructType)), unless(cxxThisExpr()))); + const auto PointerToStructExpr = expr( + hasType(hasCanonicalType(PointerToStructType)), unless(cxxThisExpr())); const auto ArrayOfPointersExpr = ignoringParenImpCasts( hasType(hasCanonicalType(arrayType(hasElementType(pointerType())) @@ -166,18 +163,19 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { ignoringParenImpCasts(arraySubscriptExpr( hasBase(ArrayOfSamePointersExpr), hasIndex(ZeroLiteral))); const auto ArrayLengthExprDenom = - expr(hasParent(expr(ignoringParenImpCasts(binaryOperator( - hasOperatorName("/"), hasLHS(ignoringParenImpCasts(sizeOfExpr( - has(ArrayOfPointersExpr)))))))), + expr(hasParent(binaryOperator(hasOperatorName("/"), + hasLHS(ignoringParenImpCasts(sizeOfExpr( + has(ArrayOfPointersExpr)))))), sizeOfExpr(has(ArrayOfSamePointersZeroSubscriptExpr))); - Finder->addMatcher(expr(anyOf(sizeOfExpr(has(ignoringParenImpCasts(anyOf( - ArrayCastExpr, PointerToArrayExpr, - StructAddrOfExpr, PointerToStructExpr)))), - sizeOfExpr(has(PointerToStructType))), - unless(ArrayLengthExprDenom)) - .bind("sizeof-pointer-to-aggregate"), - this); + Finder->addMatcher( + expr(sizeOfExpr(anyOf( + has(ignoringParenImpCasts(anyOf( + ArrayCastExpr, PointerToArrayExpr, PointerToStructExpr))), + has(PointerToStructType))), + unless(ArrayLengthExprDenom)) + .bind("sizeof-pointer-to-aggregate"), + this); } // Detect expression like: sizeof(expr) <= k for a suspicious constant 'k'. diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index d9ec268650c05..35e29b9a7d136 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -15,6 +15,7 @@ add_custom_command( DEPENDS ${clang_tidy_confusable_chars_gen_target} ConfusableTable/confusables.txt) add_custom_target(genconfusable DEPENDS Confusables.inc) +set_target_properties(genconfusable PROPERTIES FOLDER "Clang Tools Extra/Sourcegenning") add_clang_library(clangTidyMiscModule ConstCorrectnessCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp index 7a021fe14436a..ea4d99586c711 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp @@ -177,9 +177,11 @@ matchTrailingTemplateParam(const FunctionTemplateDecl *FunctionTemplate) { dyn_cast(LastParam)) { if (LastTemplateParam->hasDefaultArgument() && LastTemplateParam->getIdentifier() == nullptr) { - return {matchEnableIfSpecialization( - LastTemplateParam->getDefaultArgumentInfo()->getTypeLoc()), - LastTemplateParam}; + return { + matchEnableIfSpecialization(LastTemplateParam->getDefaultArgument() + .getTypeSourceInfo() + ->getTypeLoc()), + LastTemplateParam}; } } return {}; diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index 74152c6034510..28f5eada6d825 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -50,7 +50,9 @@ StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind, case CK_PointerToBoolean: case CK_MemberPointerToBoolean: // Fall-through on purpose. - return Context.getLangOpts().CPlusPlus11 ? "nullptr" : "0"; + return (Context.getLangOpts().CPlusPlus11 || Context.getLangOpts().C23) + ? "nullptr" + : "0"; default: llvm_unreachable("Unexpected cast kind"); @@ -165,6 +167,12 @@ bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) { void fixGenericExprCastFromBool(DiagnosticBuilder &Diag, const ImplicitCastExpr *Cast, ASTContext &Context, StringRef OtherType) { + if (!Context.getLangOpts().CPlusPlus) { + Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(), + (Twine("(") + OtherType + ")").str()); + return; + } + const Expr *SubExpr = Cast->getSubExpr(); const bool NeedParens = !isa(SubExpr->IgnoreImplicit()); const bool NeedSpace = needsSpacePrefix(Cast->getBeginLoc(), Context); @@ -267,6 +275,10 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { auto BoolXor = binaryOperator(hasOperatorName("^"), hasLHS(ImplicitCastFromBool), hasRHS(ImplicitCastFromBool)); + auto ComparisonInCall = allOf( + hasParent(callExpr()), + hasSourceExpression(binaryOperator(hasAnyOperatorName("==", "!=")))); + Finder->addMatcher( traverse(TK_AsIs, implicitCastExpr( @@ -281,6 +293,8 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))), // Exclude cases common to implicit cast to and from bool. unless(ExceptionCases), unless(has(BoolXor)), + // Exclude C23 cases common to implicit cast to bool. + unless(ComparisonInCall), // Retrieve also parent statement, to check if we need // additional parens in replacement. optionally(hasParent(stmt().bind("parentStmt"))), diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp index e811f5519de2c..88e4886cd0df9 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp @@ -123,6 +123,9 @@ static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) { if (const auto *Method = dyn_cast(ND)) { if (const CXXMethodDecl *Overridden = getOverrideMethod(Method)) Canonical = cast(Overridden->getCanonicalDecl()); + else if (const FunctionTemplateDecl *Primary = Method->getPrimaryTemplate()) + if (const FunctionDecl *TemplatedDecl = Primary->getTemplatedDecl()) + Canonical = cast(TemplatedDecl->getCanonicalDecl()); if (Canonical != ND) return Canonical; diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 06b949bc4a2b5..de103e011c708 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -247,8 +247,12 @@ fetchTemplateParameters(const TemplateParameterList *Params, if (!TTP->getName().empty()) P.Name = TTP->getNameAsString(); - if (TTP->hasDefaultArgument()) - P.Default = TTP->getDefaultArgument().getAsString(PP); + if (TTP->hasDefaultArgument()) { + P.Default.emplace(); + llvm::raw_string_ostream Out(*P.Default); + TTP->getDefaultArgument().getArgument().print(PP, Out, + /*IncludeType=*/false); + } } else if (const auto *NTTP = dyn_cast(Param)) { P.Type = printType(NTTP, PP); @@ -258,7 +262,8 @@ fetchTemplateParameters(const TemplateParameterList *Params, if (NTTP->hasDefaultArgument()) { P.Default.emplace(); llvm::raw_string_ostream Out(*P.Default); - NTTP->getDefaultArgument()->printPretty(Out, nullptr, PP); + NTTP->getDefaultArgument().getArgument().print(PP, Out, + /*IncludeType=*/false); } } else if (const auto *TTPD = dyn_cast(Param)) { P.Type = printType(TTPD, PP); diff --git a/clang-tools-extra/clangd/test/infinite-instantiation.test b/clang-tools-extra/clangd/test/infinite-instantiation.test index 85a1b656f4908..a9c787c77027c 100644 --- a/clang-tools-extra/clangd/test/infinite-instantiation.test +++ b/clang-tools-extra/clangd/test/infinite-instantiation.test @@ -1,5 +1,6 @@ -// RUN: cp %s %t.cpp -// RUN: not clangd -check=%t.cpp 2>&1 | FileCheck -strict-whitespace %s +// RUN: rm -rf %t.dir && mkdir -p %t.dir +// RUN: echo '[{"directory": "%/t.dir", "command": "clang -ftemplate-depth=100 -x c++ %/s", "file": "%/s"}]' > %t.dir/compile_commands.json +// RUN: not clangd --compile-commands-dir=%t.dir -check=%s 2>&1 | FileCheck -strict-whitespace %s // CHECK: [template_recursion_depth_exceeded] diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index 7f1ae5c43d80c..0d4628ccf25d8 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -29,6 +29,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/../quality/CompletionModel.cmake) gen_decision_forest(${CMAKE_CURRENT_SOURCE_DIR}/decision_forest_model DecisionForestRuntimeTest ::ns1::ns2::test::Example) add_custom_target(ClangdUnitTests) +set_target_properties(ClangdUnitTests PROPERTIES FOLDER "Clang Tools Extra/Tests") add_unittest(ClangdUnitTests ClangdTests Annotations.cpp ASTTests.cpp diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 0b2273f0a9a6e..3220a5a6a9825 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -836,7 +836,9 @@ TEST_F(TargetDeclTest, OverloadExpr) { [[delete]] x; } )cpp"; - EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept"); + // Sized deallocation is enabled by default in C++14 onwards. + EXPECT_DECLS("CXXDeleteExpr", + "void operator delete(void *, unsigned long) noexcept"); } TEST_F(TargetDeclTest, DependentExprs) { diff --git a/clang-tools-extra/docs/CMakeLists.txt b/clang-tools-extra/docs/CMakeLists.txt index 8f442e1f661ed..272db266b5054 100644 --- a/clang-tools-extra/docs/CMakeLists.txt +++ b/clang-tools-extra/docs/CMakeLists.txt @@ -77,6 +77,7 @@ if (DOXYGEN_FOUND) COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating clang doxygen documentation." VERBATIM) + set_target_properties(doxygen-clang-tools PROPERTIES FOLDER "Clang Tools Extra/Docs") if (LLVM_BUILD_DOCS) add_dependencies(doxygen doxygen-clang-tools) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6a9892bada915..3e3195f6f6813 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -375,12 +375,15 @@ Changes in existing checks ` check in `GetConfigPerFile` mode by resolving symbolic links to header files. Fixed handling of Hungarian Prefix when configured to `LowerCase`. Added support for renaming designated - initializers. Added support for renaming macro arguments. + initializers. Added support for renaming macro arguments. Fixed renaming + conflicts arising from out-of-line member function template definitions. - Improved :doc:`readability-implicit-bool-conversion ` check to provide valid fix suggestions for ``static_cast`` without a preceding space and - fixed problem with duplicate parentheses in double implicit casts. + fixed problem with duplicate parentheses in double implicit casts. Corrected + the fix suggestions for C23 and later by using C-style casts instead of + ``static_cast``. - Improved :doc:`readability-redundant-inline-specifier ` check to properly diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst index 1ea67a0b55e96..1ab21ffeb4228 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst @@ -96,8 +96,8 @@ The rules for generating fix-it hints are: - ``if (!pointer)`` is changed to ``if (pointer == nullptr)``, - in case of conversions from bool to other built-in types, an explicit - ``static_cast`` is proposed to make it clear that a conversion is taking - place: + ``static_cast`` (or a C-style cast since C23) is proposed to make it clear + that a conversion is taking place: - ``int integer = boolean;`` is changed to ``int integer = static_cast(boolean);``, diff --git a/clang-tools-extra/include-cleaner/unittests/CMakeLists.txt b/clang-tools-extra/include-cleaner/unittests/CMakeLists.txt index 1e89534b51116..416535649f622 100644 --- a/clang-tools-extra/include-cleaner/unittests/CMakeLists.txt +++ b/clang-tools-extra/include-cleaner/unittests/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ) add_custom_target(ClangIncludeCleanerUnitTests) +set_target_properties(ClangIncludeCleanerUnitTests PROPERTIES FOLDER "Clang Tools Extra/Tests") add_unittest(ClangIncludeCleanerUnitTests ClangIncludeCleanerTests AnalysisTest.cpp FindHeadersTest.cpp diff --git a/clang-tools-extra/pseudo/include/CMakeLists.txt b/clang-tools-extra/pseudo/include/CMakeLists.txt index 2334cfa12e337..619b00f34a5ca 100644 --- a/clang-tools-extra/pseudo/include/CMakeLists.txt +++ b/clang-tools-extra/pseudo/include/CMakeLists.txt @@ -29,3 +29,4 @@ add_custom_command(OUTPUT ${cxx_bnf_inc} add_custom_target(cxx_gen DEPENDS ${cxx_symbols_inc} ${cxx_bnf_inc} VERBATIM) +set_target_properties(cxx_gen PROPERTIES FOLDER "Clang Tools Extra/Sourcegenning") diff --git a/clang-tools-extra/pseudo/tool/CMakeLists.txt b/clang-tools-extra/pseudo/tool/CMakeLists.txt index 49e1dc29a5a4e..bead383228396 100644 --- a/clang-tools-extra/pseudo/tool/CMakeLists.txt +++ b/clang-tools-extra/pseudo/tool/CMakeLists.txt @@ -26,4 +26,5 @@ add_custom_command(OUTPUT HTMLForestResources.inc DEPENDS ${CLANG_SOURCE_DIR}/utils/bundle_resources.py HTMLForest.css HTMLForest.js HTMLForest.html VERBATIM) add_custom_target(clang-pseudo-resources DEPENDS HTMLForestResources.inc) +set_target_properties(clang-pseudo-resources PROPERTIES FOLDER "Clang Tools Extra/Resources") add_dependencies(clang-pseudo clang-pseudo-resources) diff --git a/clang-tools-extra/pseudo/unittests/CMakeLists.txt b/clang-tools-extra/pseudo/unittests/CMakeLists.txt index 821ca4d0652e1..53583ceb61864 100644 --- a/clang-tools-extra/pseudo/unittests/CMakeLists.txt +++ b/clang-tools-extra/pseudo/unittests/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS ) add_custom_target(ClangPseudoUnitTests) +set_target_properties(ClangPseudoUnitTests PROPERTIES FOLDER "Clang Tools Extra/Tests") add_unittest(ClangPseudoUnitTests ClangPseudoTests BracketTest.cpp CXXTest.cpp diff --git a/clang-tools-extra/test/CMakeLists.txt b/clang-tools-extra/test/CMakeLists.txt index 7a1c168e22f97..50546f62259ca 100644 --- a/clang-tools-extra/test/CMakeLists.txt +++ b/clang-tools-extra/test/CMakeLists.txt @@ -97,7 +97,6 @@ add_lit_testsuite(check-clang-extra "Running clang-tools-extra/test" ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CLANG_TOOLS_TEST_DEPS} ) -set_target_properties(check-clang-extra PROPERTIES FOLDER "Clang extra tools' tests") add_lit_testsuites(CLANG-EXTRA ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${CLANG_TOOLS_TEST_DEPS} diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp index 78f021144b2e1..f86fe8a4c5b14 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/new-delete-overloads.cpp @@ -12,16 +12,6 @@ struct S { // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope void *operator new(size_t size) noexcept(false); -struct T { - // Sized deallocations are not enabled by default, and so this new/delete pair - // does not match. However, we expect only one warning, for the new, because - // the operator delete is a placement delete and we do not warn on mismatching - // placement operations. - // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope - void *operator new(size_t size) noexcept; - void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled -}; - struct U { void *operator new(size_t size) noexcept; void operator delete(void *ptr) noexcept; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-outofline.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-outofline.cpp new file mode 100644 index 0000000000000..f807875e27698 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-outofline.cpp @@ -0,0 +1,30 @@ +// RUN: %check_clang_tidy %s readability-identifier-naming %t -std=c++20 \ +// RUN: --config='{CheckOptions: { \ +// RUN: readability-identifier-naming.MethodCase: CamelCase, \ +// RUN: }}' + +namespace SomeNamespace { +namespace Inner { + +class SomeClass { +public: + template + int someMethod(); +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for method 'someMethod' [readability-identifier-naming] +// CHECK-FIXES: {{^}} int SomeMethod(); +}; +template +int SomeClass::someMethod() { +// CHECK-FIXES: {{^}}int SomeClass::SomeMethod() { + return 5; +} + +} // namespace Inner + +void someFunc() { + Inner::SomeClass S; + S.someMethod(); +// CHECK-FIXES: {{^}} S.SomeMethod(); +} + +} // namespace SomeNamespace diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c new file mode 100644 index 0000000000000..a8c69858f76b6 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c @@ -0,0 +1,354 @@ +// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t -- -- -std=c23 + +#undef NULL +#define NULL 0L + +void functionTakingBool(bool); +void functionTakingInt(int); +void functionTakingUnsignedLong(unsigned long); +void functionTakingChar(char); +void functionTakingFloat(float); +void functionTakingDouble(double); +void functionTakingSignedChar(signed char); + + +////////// Implicit conversion from bool. + +void implicitConversionFromBoolSimpleCases() { + bool boolean = true; + + functionTakingBool(boolean); + + functionTakingInt(boolean); + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion] + // CHECK-FIXES: functionTakingInt((int)boolean); + + functionTakingUnsignedLong(boolean); + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long' + // CHECK-FIXES: functionTakingUnsignedLong((unsigned long)boolean); + + functionTakingChar(boolean); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'bool' -> 'char' + // CHECK-FIXES: functionTakingChar((char)boolean); + + functionTakingFloat(boolean); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float' + // CHECK-FIXES: functionTakingFloat((float)boolean); + + functionTakingDouble(boolean); + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'double' + // CHECK-FIXES: functionTakingDouble((double)boolean); +} + +float implicitConversionFromBoolInReturnValue() { + bool boolean = false; + return boolean; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'bool' -> 'float' + // CHECK-FIXES: return (float)boolean; +} + +void implicitConversionFromBoolInSingleBoolExpressions(bool b1, bool b2) { + bool boolean = true; + boolean = b1 ^ b2; + boolean |= !b1 || !b2; + boolean &= b1; + + int integer = boolean - 3; + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: int integer = (int)boolean - 3; + + float floating = boolean / 0.3f; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'float' + // CHECK-FIXES: float floating = (float)boolean / 0.3f; + + char character = boolean; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: implicit conversion 'bool' -> 'char' + // CHECK-FIXES: char character = (char)boolean; +} + +void implicitConversionFromBoolInComplexBoolExpressions() { + bool boolean = true; + bool anotherBoolean = false; + + int integer = boolean && anotherBoolean; + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit conversion 'bool' -> 'int' + // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: int integer = (int)boolean && (int)anotherBoolean; + + float floating = (boolean || anotherBoolean) * 0.3f; + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: implicit conversion 'bool' -> 'int' + // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: float floating = ((int)boolean || (int)anotherBoolean) * 0.3f; + + double doubleFloating = (boolean && (anotherBoolean || boolean)) * 0.3; + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'bool' -> 'int' + // CHECK-MESSAGES: :[[@LINE-2]]:40: warning: implicit conversion 'bool' -> 'int' + // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: double doubleFloating = ((int)boolean && ((int)anotherBoolean || (int)boolean)) * 0.3; +} + +void implicitConversionFromBoolLiterals() { + functionTakingInt(true); + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: functionTakingInt(1); + + functionTakingUnsignedLong(false); + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long' + // CHECK-FIXES: functionTakingUnsignedLong(0u); + + functionTakingSignedChar(true); + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'bool' -> 'signed char' + // CHECK-FIXES: functionTakingSignedChar(1); + + functionTakingFloat(false); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float' + // CHECK-FIXES: functionTakingFloat(0.0f); + + functionTakingDouble(true); + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'double' + // CHECK-FIXES: functionTakingDouble(1.0); +} + +void implicitConversionFromBoolInComparisons() { + bool boolean = true; + int integer = 0; + + functionTakingBool(boolean == integer); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: functionTakingBool((int)boolean == integer); + + functionTakingBool(integer != boolean); + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: functionTakingBool(integer != (int)boolean); +} + +void ignoreBoolComparisons() { + bool boolean = true; + bool anotherBoolean = false; + + functionTakingBool(boolean == anotherBoolean); + functionTakingBool(boolean != anotherBoolean); +} + +void ignoreExplicitCastsFromBool() { + bool boolean = true; + + int integer = (int)boolean + 3; + float floating = (float)boolean * 0.3f; + char character = (char)boolean; +} + +void ignoreImplicitConversionFromBoolInMacroExpansions() { + bool boolean = true; + + #define CAST_FROM_BOOL_IN_MACRO_BODY boolean + 3 + int integerFromMacroBody = CAST_FROM_BOOL_IN_MACRO_BODY; + + #define CAST_FROM_BOOL_IN_MACRO_ARGUMENT(x) x + 3 + int integerFromMacroArgument = CAST_FROM_BOOL_IN_MACRO_ARGUMENT(boolean); +} + +////////// Implicit conversions to bool. + +void implicitConversionToBoolSimpleCases() { + int integer = 10; + functionTakingBool(integer); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: functionTakingBool(integer != 0); + + unsigned long unsignedLong = 10; + functionTakingBool(unsignedLong); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'unsigned long' -> 'bool' + // CHECK-FIXES: functionTakingBool(unsignedLong != 0u); + + float floating = 0.0f; + functionTakingBool(floating); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool' + // CHECK-FIXES: functionTakingBool(floating != 0.0f); + + double doubleFloating = 1.0f; + functionTakingBool(doubleFloating); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool' + // CHECK-FIXES: functionTakingBool(doubleFloating != 0.0); + + signed char character = 'a'; + functionTakingBool(character); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'signed char' -> 'bool' + // CHECK-FIXES: functionTakingBool(character != 0); + + int* pointer = nullptr; + functionTakingBool(pointer); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int *' -> 'bool' + // CHECK-FIXES: functionTakingBool(pointer != nullptr); +} + +void implicitConversionToBoolInSingleExpressions() { + int integer = 10; + bool boolComingFromInt; + boolComingFromInt = integer; + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: boolComingFromInt = (integer != 0); + + float floating = 10.0f; + bool boolComingFromFloat; + boolComingFromFloat = floating; + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'float' -> 'bool' + // CHECK-FIXES: boolComingFromFloat = (floating != 0.0f); + + signed char character = 'a'; + bool boolComingFromChar; + boolComingFromChar = character; + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'signed char' -> 'bool' + // CHECK-FIXES: boolComingFromChar = (character != 0); + + int* pointer = nullptr; + bool boolComingFromPointer; + boolComingFromPointer = pointer; + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion 'int *' -> 'bool' + // CHECK-FIXES: boolComingFromPointer = (pointer != nullptr); +} + +void implicitConversionToBoolInComplexExpressions() { + bool boolean = true; + + int integer = 10; + int anotherInteger = 20; + bool boolComingFromInteger; + boolComingFromInteger = integer + anotherInteger; + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: boolComingFromInteger = ((integer + anotherInteger) != 0); +} + +void implicitConversionInNegationExpressions() { + int integer = 10; + bool boolComingFromNegatedInt; + boolComingFromNegatedInt = !integer; + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: boolComingFromNegatedInt = ((!integer) != 0); +} + +bool implicitConversionToBoolInReturnValue() { + float floating = 1.0f; + return floating; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool' + // CHECK-FIXES: return floating != 0.0f; +} + +void implicitConversionToBoolFromLiterals() { + functionTakingBool(0); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: functionTakingBool(false); + + functionTakingBool(1); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool(2ul); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'unsigned long' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool(0.0f); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool' + // CHECK-FIXES: functionTakingBool(false); + + functionTakingBool(1.0f); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool(2.0); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool('\0'); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: functionTakingBool(false); + + functionTakingBool('a'); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool(""); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'char *' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool("abc"); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'char *' -> 'bool' + // CHECK-FIXES: functionTakingBool(true); + + functionTakingBool(NULL); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'long' -> 'bool' + // CHECK-FIXES: functionTakingBool(false); +} + +void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() { + functionTakingBool(-0); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: functionTakingBool((-0) != 0); + + functionTakingBool(-0.0f); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool' + // CHECK-FIXES: functionTakingBool((-0.0f) != 0.0f); + + functionTakingBool(-0.0); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool' + // CHECK-FIXES: functionTakingBool((-0.0) != 0.0); +} + +void ignoreExplicitCastsToBool() { + int integer = 10; + bool boolComingFromInt = (bool)integer; + + float floating = 10.0f; + bool boolComingFromFloat = (bool)floating; + + char character = 'a'; + bool boolComingFromChar = (bool)character; + + int* pointer = nullptr; + bool booleanComingFromPointer = (bool)pointer; +} + +void ignoreImplicitConversionToBoolInMacroExpansions() { + int integer = 3; + + #define CAST_TO_BOOL_IN_MACRO_BODY integer && false + bool boolFromMacroBody = CAST_TO_BOOL_IN_MACRO_BODY; + + #define CAST_TO_BOOL_IN_MACRO_ARGUMENT(x) x || true + bool boolFromMacroArgument = CAST_TO_BOOL_IN_MACRO_ARGUMENT(integer); +} + +int implicitConversionReturnInt() +{ + return true; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: return 1 +} + +int implicitConversionReturnIntWithParens() +{ + return (true); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' + // CHECK-FIXES: return 1 +} + +bool implicitConversionReturnBool() +{ + return 1; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: return true +} + +bool implicitConversionReturnBoolWithParens() +{ + return (1); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' + // CHECK-FIXES: return true +} + +int keepCompactReturnInC_PR71848() { + bool foo = false; + return( foo ); +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: implicit conversion 'bool' -> 'int' [readability-implicit-bool-conversion] +// CHECK-FIXES: return(int)( foo ); +} diff --git a/clang-tools-extra/unittests/CMakeLists.txt b/clang-tools-extra/unittests/CMakeLists.txt index 086a68e638307..77311540e719f 100644 --- a/clang-tools-extra/unittests/CMakeLists.txt +++ b/clang-tools-extra/unittests/CMakeLists.txt @@ -1,5 +1,5 @@ add_custom_target(ExtraToolsUnitTests) -set_target_properties(ExtraToolsUnitTests PROPERTIES FOLDER "Extra Tools Unit Tests") +set_target_properties(ExtraToolsUnitTests PROPERTIES FOLDER "Clang Tools Extra/Tests") function(add_extra_unittest test_dirname) add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN}) diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index c20ce47a12abb..2ac0bccb42f50 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.20.0) +set(LLVM_SUBPROJECT_TITLE "Clang") if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS) set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) @@ -349,10 +350,7 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wno-long-long") endif () - check_cxx_compiler_flag("-Werror -Wnested-anon-types" CXX_SUPPORTS_NO_NESTED_ANON_TYPES_FLAG) - if( CXX_SUPPORTS_NO_NESTED_ANON_TYPES_FLAG ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types" ) - endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types" ) endif () # Determine HOST_LINK_VERSION on Darwin. @@ -394,7 +392,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) # Installing the headers needs to depend on generating any public # tablegen'd headers. add_custom_target(clang-headers DEPENDS clang-tablegen-targets) - set_target_properties(clang-headers PROPERTIES FOLDER "Misc") + set_target_properties(clang-headers PROPERTIES FOLDER "Clang/Resources") if(NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-clang-headers DEPENDS clang-headers @@ -402,6 +400,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) endif() add_custom_target(bash-autocomplete DEPENDS utils/bash-autocomplete.sh) + set_target_properties(bash-autocomplete PROPERTIES FOLDER "Clang/Misc") install(FILES utils/bash-autocomplete.sh DESTINATION "${CMAKE_INSTALL_DATADIR}/clang" COMPONENT bash-autocomplete) @@ -482,7 +481,7 @@ add_custom_target(clang-tablegen-targets omp_gen ClangDriverOptions ${CLANG_TABLEGEN_TARGETS}) -set_target_properties(clang-tablegen-targets PROPERTIES FOLDER "Misc") +set_target_properties(clang-tablegen-targets PROPERTIES FOLDER "Clang/Tablegenning/Targets") list(APPEND LLVM_COMMON_DEPENDS clang-tablegen-targets) # Force target to be built as soon as possible. Clang modules builds depend @@ -547,7 +546,7 @@ endif() # Custom target to install all clang libraries. add_custom_target(clang-libraries) -set_target_properties(clang-libraries PROPERTIES FOLDER "Misc") +set_target_properties(clang-libraries PROPERTIES FOLDER "Clang/Install") if(NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-clang-libraries diff --git a/clang/bindings/python/tests/CMakeLists.txt b/clang/bindings/python/tests/CMakeLists.txt index c4cd2539e9d6c..2543cf739463d 100644 --- a/clang/bindings/python/tests/CMakeLists.txt +++ b/clang/bindings/python/tests/CMakeLists.txt @@ -11,7 +11,7 @@ add_custom_target(check-clang-python WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..) set(RUN_PYTHON_TESTS TRUE) -set_target_properties(check-clang-python PROPERTIES FOLDER "Clang tests") +set_target_properties(check-clang-python PROPERTIES FOLDER "Clang/Tests") # Tests require libclang.so which is only built with LLVM_ENABLE_PIC=ON if(NOT LLVM_ENABLE_PIC) diff --git a/clang/cmake/caches/CrossWinToARMLinux.cmake b/clang/cmake/caches/CrossWinToARMLinux.cmake index 736a54ece550c..62e87c6c62f85 100644 --- a/clang/cmake/caches/CrossWinToARMLinux.cmake +++ b/clang/cmake/caches/CrossWinToARMLinux.cmake @@ -89,6 +89,13 @@ endif() message(STATUS "Toolchain target to build: ${LLVM_TARGETS_TO_BUILD}") +# Allow to override libc++ ABI version. Use 2 by default. +if (NOT DEFINED LIBCXX_ABI_VERSION) + set(LIBCXX_ABI_VERSION 2) +endif() + +message(STATUS "Toolchain's Libc++ ABI version: ${LIBCXX_ABI_VERSION}") + if (NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") endif() @@ -109,8 +116,15 @@ set(CLANG_DEFAULT_OBJCOPY "llvm-objcopy" CACHE STRING "") set(CLANG_DEFAULT_RTLIB "compiler-rt" CACHE STRING "") set(CLANG_DEFAULT_UNWINDLIB "libunwind" CACHE STRING "") -if(WIN32) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "") +if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY AND WIN32) + #Note: Always specify MT DLL for the LLDB build configurations on Windows host. + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebugDLL" CACHE STRING "") + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "") + endif() + # Grab all ucrt/vcruntime related DLLs into the binary installation folder. + set(CMAKE_INSTALL_UCRT_LIBRARIES ON CACHE BOOL "") endif() # Set up RPATH for the target runtime/builtin libraries. @@ -127,6 +141,15 @@ set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_INSTALL_RPATH set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "") set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_LLVM_CMAKE_DIR "${LLVM_PROJECT_DIR}/llvm/cmake/modules" CACHE PATH "") +if (DEFINED TOOLCHAIN_TARGET_COMPILER_FLAGS) + foreach(lang C;CXX;ASM) + set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_${lang}_FLAGS "${TOOLCHAIN_TARGET_COMPILER_FLAGS}" CACHE STRING "") + endforeach() +endif() +foreach(type SHARED;MODULE;EXE) + set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") +endforeach() + set(LLVM_RUNTIME_TARGETS "${TOOLCHAIN_TARGET_TRIPLE}" CACHE STRING "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") @@ -137,6 +160,15 @@ set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_SYSROOT set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_INSTALL_RPATH "${RUNTIMES_INSTALL_RPATH}" CACHE STRING "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "") +if (DEFINED TOOLCHAIN_TARGET_COMPILER_FLAGS) + foreach(lang C;CXX;ASM) + set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_${lang}_FLAGS "${TOOLCHAIN_TARGET_COMPILER_FLAGS}" CACHE STRING "") + endforeach() +endif() +foreach(type SHARED;MODULE;EXE) + set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") +endforeach() + set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_BUILTINS ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") @@ -164,7 +196,7 @@ set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_ENABLE_SHARED set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") -set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ABI_VERSION 2 CACHE STRING "") +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ABI_VERSION ${LIBCXX_ABI_VERSION} CACHE STRING "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") #!!! set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index d5546e20873b3..66e764968e85c 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -19,7 +19,6 @@ set(LLVM_ENABLE_LLD ON CACHE BOOL "") set(LLVM_ENABLE_LTO ON CACHE BOOL "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_ENABLE_PLUGINS OFF CACHE BOOL "") -set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_UNWIND_TABLES OFF CACHE BOOL "") set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 30a3b9116a461..4d3af3ad3f403 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -12,7 +12,6 @@ set(LLVM_ENABLE_DIA_SDK OFF CACHE BOOL "") set(LLVM_ENABLE_LIBEDIT OFF CACHE BOOL "") set(LLVM_ENABLE_LIBXML2 OFF CACHE BOOL "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") -set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_UNWIND_TABLES OFF CACHE BOOL "") set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") @@ -34,7 +33,6 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH LibXml2_ROOT LLVM_ENABLE_CURL LLVM_ENABLE_HTTPLIB - LLVM_ENABLE_TERMINFO LLVM_ENABLE_LIBEDIT CURL_ROOT OpenSSL_ROOT @@ -47,11 +45,6 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH CURSES_LIBRARIES PANEL_LIBRARIES - # Deprecated - Terminfo_ROOT - - Terminfo_LIBRARIES - # Deprecated LibEdit_ROOT diff --git a/clang/cmake/caches/VectorEngine.cmake b/clang/cmake/caches/VectorEngine.cmake index 2f968a21cc407..b429fb0997d7a 100644 --- a/clang/cmake/caches/VectorEngine.cmake +++ b/clang/cmake/caches/VectorEngine.cmake @@ -13,9 +13,7 @@ # ninja # -# Disable TERMINFO, ZLIB, and ZSTD for VE since there is no pre-compiled -# libraries. -set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") +# Disable ZLIB, and ZSTD for VE since there is no pre-compiled libraries. set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") set(LLVM_ENABLE_ZSTD OFF CACHE BOOL "") diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake index 75b0080f67156..a5ef639187d9d 100644 --- a/clang/cmake/modules/AddClang.cmake +++ b/clang/cmake/modules/AddClang.cmake @@ -26,7 +26,6 @@ function(clang_tablegen) if(CTG_TARGET) add_public_tablegen_target(${CTG_TARGET}) - set_target_properties( ${CTG_TARGET} PROPERTIES FOLDER "Clang tablegenning") set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET}) endif() endfunction(clang_tablegen) @@ -138,13 +137,11 @@ macro(add_clang_library name) endif() endforeach() - set_target_properties(${name} PROPERTIES FOLDER "Clang libraries") set_clang_windows_version_resource_properties(${name}) endmacro(add_clang_library) macro(add_clang_executable name) add_llvm_executable( ${name} ${ARGN} ) - set_target_properties(${name} PROPERTIES FOLDER "Clang executables") set_clang_windows_version_resource_properties(${name}) endmacro(add_clang_executable) diff --git a/clang/docs/CMakeLists.txt b/clang/docs/CMakeLists.txt index 4163dd2d90ad5..51e9db29f887f 100644 --- a/clang/docs/CMakeLists.txt +++ b/clang/docs/CMakeLists.txt @@ -78,6 +78,7 @@ if (LLVM_ENABLE_DOXYGEN) COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating clang doxygen documentation." VERBATIM) + set_target_properties(doxygen-clang PROPERTIES FOLDER "Clang/Docs") if (LLVM_BUILD_DOCS) add_dependencies(doxygen doxygen-clang) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index a09c409f8f91a..46f99d0bbdd06 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -4403,6 +4403,7 @@ immediately after the name being declared. For example, this applies the GNU ``unused`` attribute to ``a`` and ``f``, and also applies the GNU ``noreturn`` attribute to ``f``. +Examples: .. code-block:: c++ [[gnu::unused]] int a, f [[gnu::noreturn]] (); @@ -4412,6 +4413,42 @@ Target-Specific Extensions Clang supports some language features conditionally on some targets. +AMDGPU Language Extensions +-------------------------- + +__builtin_amdgcn_fence +^^^^^^^^^^^^^^^^^^^^^^ + +``__builtin_amdgcn_fence`` emits a fence. + +* ``unsigned`` atomic ordering, e.g. ``__ATOMIC_ACQUIRE`` +* ``const char *`` synchronization scope, e.g. ``workgroup`` +* Zero or more ``const char *`` address spaces names. + +The address spaces arguments must be one of the following string literals: + +* ``"local"`` +* ``"global"`` + +If one or more address space name are provided, the code generator will attempt +to emit potentially faster instructions that order access to at least those +address spaces. +Emitting such instructions may not always be possible and the compiler is free +to fence more aggressively. + +If no address spaces names are provided, all address spaces are fenced. + +.. code-block:: c++ + + // Fence all address spaces. + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "workgroup"); + __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, "agent"); + + // Fence only requested address spaces. + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "workgroup", "local") + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "workgroup", "local", "global") + + ARM/AArch64 Language Extensions ------------------------------- @@ -5602,4 +5639,4 @@ Compiling different TUs depending on these flags (including use of ``std::hardware_constructive_interference`` or ``std::hardware_destructive_interference``) with different compilers, macro definitions, or architecture flags will lead to ODR violations and should be -avoided. \ No newline at end of file +avoided. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 81e9d0423f96a..37a664b14fab1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -59,6 +59,18 @@ C++ Specific Potentially Breaking Changes - Clang now performs semantic analysis for unary operators with dependent operands that are known to be of non-class non-enumeration type prior to instantiation. + This change uncovered a bug in libstdc++ 14.1.0 which may cause compile failures + on systems using that version of libstdc++ and Clang 19, with an error that looks + something like this: + + .. code-block:: text + + :4:5: error: expression is not assignable + 4 | ++this; + | ^ ~~~~ + + To fix this, update libstdc++ to version 14.1.1 or greater. + ABI Changes in This Version --------------------------- - Fixed Microsoft name mangling of implicitly defined variables used for thread @@ -155,6 +167,11 @@ C++17 Feature Support files because they may not be stable across multiple TUs (the values may vary based on compiler version as well as CPU tuning). #GH60174 +C++14 Feature Support +^^^^^^^^^^^^^^^^^^^^^ +- Sized deallocation is enabled by default in C++14 onwards. The user may specify + ``-fno-sized-deallocation`` to disable it if there are some regressions. + C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ @@ -317,13 +334,18 @@ New Compiler Flags - ``-fexperimental-late-parse-attributes`` enables an experimental feature to allow late parsing certain attributes in specific contexts where they would - not normally be late parsed. + not normally be late parsed. Currently this allows late parsing the + `counted_by` attribute in C. See `Attribute Changes in Clang`_. - ``-fseparate-named-sections`` uses separate unique sections for global symbols in named special sections (i.e. symbols annotated with ``__attribute__((section(...)))``. This enables linker GC to collect unused symbols without having to use a per-symbol section. +- ``-fms-define-stdc`` and its clang-cl counterpart ``/Zc:__STDC__``. + Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when + MSVC compatibility mode is used. It has no effect for C++ code. + Deprecated Compiler Flags ------------------------- @@ -406,6 +428,24 @@ Attribute Changes in Clang - The ``clspv_libclc_builtin`` attribute has been added to allow clspv (`OpenCL-C to Vulkan SPIR-V compiler `_) to identify functions coming from libclc (`OpenCL-C builtin library `_). +- The ``counted_by`` attribute is now allowed on pointers that are members of a + struct in C. + +- The ``counted_by`` attribute can now be late parsed in C when + ``-fexperimental-late-parse-attributes`` is passed but only when attribute is + used in the declaration attribute position. This allows using the + attribute on existing code where it previously impossible to do so without + re-ordering struct field declarations would break ABI as shown below. + + .. code-block:: c + + struct BufferTy { + /* Refering to `count` requires late parsing */ + char* buffer __counted_by(count); + /* Swapping `buffer` and `count` to avoid late parsing would break ABI */ + size_t count; + }; + Improvements to Clang's diagnostics ----------------------------------- @@ -592,6 +632,8 @@ Bug Fixes in This Version Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330) + Bug Fixes to Attribute Support ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -694,7 +736,6 @@ Bug Fixes to C++ Support from being explicitly specialized for a given implicit instantiation of the class template. - Fixed a crash when ``this`` is used in a dependent class scope function template specialization that instantiates to a static member function. - - Fix crash when inheriting from a cv-qualified type. Fixes #GH35603 - Fix a crash when the using enum declaration uses an anonymous enumeration. Fixes (#GH86790). - Handled an edge case in ``getFullyPackExpandedSize`` so that we now avoid a false-positive diagnostic. (#GH84220) @@ -749,6 +790,18 @@ Bug Fixes to C++ Support - Clang now correctly diagnoses when the current instantiation is used as an incomplete base class. - Clang no longer treats ``constexpr`` class scope function template specializations of non-static members as implicitly ``const`` in language modes after C++11. +- Fixed a crash when trying to emit captures in a lambda call operator with an explicit object + parameter that is called on a derived type of the lambda. + Fixes (#GH87210), (GH89541). +- Clang no longer tries to check if an expression is immediate-escalating in an unevaluated context. + Fixes (#GH91308). +- Fix a crash caused by a regression in the handling of ``source_location`` + in dependent contexts. Fixes (#GH92680). +- Fixed a crash when diagnosing failed conversions involving template parameter + packs. (#GH93076) +- Fixed a regression introduced in Clang 18 causing a static function overloading a non-static function + with the same parameters not to be diagnosed. (Fixes #GH93456). +- Clang now diagnoses unexpanded parameter packs in attributes. (Fixes #GH93269). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -761,12 +814,15 @@ Miscellaneous Bug Fixes - Fixed an infinite recursion in ASTImporter, on return type declared inside body of C++11 lambda without trailing return (#GH68775). +- Fixed declaration name source location of instantiated function definitions (GH71161). +- Improve diagnostic output to print an expression instead of 'no argument` when comparing Values as template arguments. Miscellaneous Clang Crashes Fixed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Do not attempt to dump the layout of dependent types or invalid declarations when ``-fdump-record-layouts-complete`` is passed. Fixes #GH83684. +- Unhandled StructuralValues in the template differ (#GH93068). OpenACC Specific Changes ------------------------ @@ -780,6 +836,8 @@ AMDGPU Support X86 Support ^^^^^^^^^^^ +- Remove knl/knm specific ISA supports: AVX512PF, AVX512ER, PREFETCHWT1 + Arm and AArch64 Support ^^^^^^^^^^^^^^^^^^^^^^^ @@ -832,6 +890,10 @@ Windows Support including STL headers will no longer slow down compile times since ``intrin.h`` is not included from MSVC STL. +- When the target triple is `*-windows-msvc` strict aliasing is now disabled by default + to ensure compatibility with msvc. Previously strict aliasing was only disabled if the + driver mode was cl. + LoongArch Support ^^^^^^^^^^^^^^^^^ diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index eb8b58323da4d..3a31708a1e9de 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1179,6 +1179,47 @@ security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C) strncpy(buf, "a", 1); // warn } +security.SetgidSetuidOrder (C) +"""""""""""""""""""""""""""""" +When dropping user-level and group-level privileges in a program by using +``setuid`` and ``setgid`` calls, it is important to reset the group-level +privileges (with ``setgid``) first. Function ``setgid`` will likely fail if +the superuser privileges are already dropped. + +The checker checks for sequences of ``setuid(getuid())`` and +``setgid(getgid())`` calls (in this order). If such a sequence is found and +there is no other privilege-changing function call (``seteuid``, ``setreuid``, +``setresuid`` and the GID versions of these) in between, a warning is +generated. The checker finds only exactly ``setuid(getuid())`` calls (and the +GID versions), not for example if the result of ``getuid()`` is stored in a +variable. + +.. code-block:: c + + void test1() { + // ... + // end of section with elevated privileges + // reset privileges (user and group) to normal user + if (setuid(getuid()) != 0) { + handle_error(); + return; + } + if (setgid(getgid()) != 0) { // warning: A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail + handle_error(); + return; + } + // user-ID and group-ID are reset to normal user now + // ... + } + +In the code above the problem is that ``setuid(getuid())`` removes superuser +privileges before ``setgid(getgid())`` is called. To fix the problem the +``setgid(getgid())`` should be called first. Further attention is needed to +avoid code like ``setgid(getuid())`` (this checker does not detect bugs like +this) and always check the return value of these calls. + +This check corresponds to SEI CERT Rule `POS36-C `_. + .. _unix-checkers: unix @@ -2792,6 +2833,41 @@ Warn on mmap() calls that are both writable and executable. // code } +.. _alpha-security-putenv-stack-array: + +alpha.security.PutenvStackArray (C) +""""""""""""""""""""""""""""""""""" +Finds calls to the ``putenv`` function which pass a pointer to a stack-allocated +(automatic) array as the argument. Function ``putenv`` does not copy the passed +string, only a pointer to the data is stored and this data can be read even by +other threads. Content of a stack-allocated array is likely to be overwritten +after returning from the parent function. + +The problem can be solved by using a static array variable or dynamically +allocated memory. Even better is to avoid using ``putenv`` (it has other +problems related to memory leaks) and use ``setenv`` instead. + +The check corresponds to CERT rule +`POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument +`_. + +.. code-block:: c + + int f() { + char env[] = "NAME=value"; + return putenv(env); // putenv function should not be called with stack-allocated string + } + +There is one case where the checker can report a false positive. This is when +the stack-allocated array is used at `putenv` in a function or code branch that +does not return (calls `fork` or `exec` like function). + +Another special case is if the `putenv` is called from function `main`. Here +the stack is deallocated at the end of the program and it should be no problem +to use the stack-allocated string (a multi-threaded program may require more +attention). The checker does not warn for cases when stack space of `main` is +used at the `putenv` call. + .. _alpha-security-ReturnPtrRange: alpha.security.ReturnPtrRange (C) @@ -2818,55 +2894,6 @@ alpha.security.cert SEI CERT checkers which tries to find errors based on their `C coding rules `_. -.. _alpha-security-cert-pos-checkers: - -alpha.security.cert.pos -^^^^^^^^^^^^^^^^^^^^^^^ - -SEI CERT checkers of `POSIX C coding rules `_. - -.. _alpha-security-cert-pos-34c: - -alpha.security.cert.pos.34c -""""""""""""""""""""""""""" -Finds calls to the ``putenv`` function which pass a pointer to an automatic variable as the argument. - -.. code-block:: c - - int func(const char *var) { - char env[1024]; - int retval = snprintf(env, sizeof(env),"TEST=%s", var); - if (retval < 0 || (size_t)retval >= sizeof(env)) { - /* Handle error */ - } - - return putenv(env); // putenv function should not be called with auto variables - } - -Limitations: - - - Technically, one can pass automatic variables to ``putenv``, - but one needs to ensure that the given environment key stays - alive until it's removed or overwritten. - Since the analyzer cannot keep track of which envvars get overwritten - and when, it needs to be slightly more aggressive and warn for such - cases too, leading in some cases to false-positive reports like this: - - .. code-block:: c - - void baz() { - char env[] = "NAME=value"; - putenv(env); // false-positive warning: putenv function should not be called... - // More code... - putenv((char *)"NAME=anothervalue"); - // This putenv call overwrites the previous entry, thus that can no longer dangle. - } // 'env' array becomes dead only here. - -alpha.security.cert.env -^^^^^^^^^^^^^^^^^^^^^^^ - -SEI CERT checkers of `Environment C coding rules `_. - alpha.security.taint ^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt index b747adfb6992e..dee51e402b687 100644 --- a/clang/docs/tools/clang-formatted-files.txt +++ b/clang/docs/tools/clang-formatted-files.txt @@ -124,6 +124,7 @@ clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h clang/include/clang/Analysis/FlowSensitive/ASTOps.h +clang/include/clang/Analysis/FlowSensitive/CNFFormula.h clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -621,6 +622,7 @@ clang/tools/libclang/CXCursor.h clang/tools/scan-build-py/tests/functional/src/include/clean-one.h clang/unittests/Analysis/CFGBuildResult.h clang/unittests/Analysis/MacroExpansionContextTest.cpp +clang/unittests/Analysis/FlowSensitive/CNFFormula.cpp clang/unittests/Analysis/FlowSensitive/DataflowAnalysisContextTest.cpp clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp clang/unittests/Analysis/FlowSensitive/MapLatticeTest.cpp @@ -632,6 +634,7 @@ clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp clang/unittests/Analysis/FlowSensitive/TestingSupport.h clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp +clang/unittests/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp clang/unittests/Analysis/FlowSensitive/WatchedLiteralsSolverTest.cpp clang/unittests/AST/ASTImporterFixtures.cpp clang/unittests/AST/ASTImporterFixtures.h diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 2ce2b810d3636..a1d1d1c51cd41 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -110,6 +110,9 @@ class VarTemplateDecl; class VTableContextBase; class XRayFunctionFilter; +/// A simple array of base specifiers. +typedef SmallVector CXXCastPath; + namespace Builtin { class Context; @@ -1170,6 +1173,12 @@ class ASTContext : public RefCountedBase { /// in device compilation. llvm::DenseSet CUDAImplicitHostDeviceFunUsedByDevice; + /// For capturing lambdas with an explicit object parameter whose type is + /// derived from the lambda type, we need to perform derived-to-base + /// conversion so we can access the captures; the cast paths for that + /// are stored here. + llvm::DenseMap LambdaCastPaths; + ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins, TranslationUnitKind TUKind); diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index bf7c204e4ad73..616f92691ec32 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -695,7 +695,7 @@ class ASTNodeTraverser if (const auto *TC = D->getTypeConstraint()) Visit(TC->getImmediatelyDeclaredConstraint()); if (D->hasDefaultArgument()) - Visit(D->getDefaultArgument(), SourceRange(), + Visit(D->getDefaultArgument().getArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } @@ -704,9 +704,9 @@ class ASTNodeTraverser if (const auto *E = D->getPlaceholderTypeConstraint()) Visit(E); if (D->hasDefaultArgument()) - Visit(D->getDefaultArgument(), SourceRange(), - D->getDefaultArgStorage().getInheritedFrom(), - D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + dumpTemplateArgumentLoc( + D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) { diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 5e485ccb85a13..7fd80b90d1033 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2188,6 +2188,8 @@ class FunctionDecl : public DeclaratorDecl, void setRangeEnd(SourceLocation E) { EndRangeLoc = E; } + void setDeclarationNameLoc(DeclarationNameLoc L) { DNLoc = L; } + /// Returns the location of the ellipsis of a variadic function. SourceLocation getEllipsisLoc() const { const auto *FPT = getType()->getAs(); diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index f3d6a321ecf10..5b6a6b40b28ef 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1185,7 +1185,7 @@ class TemplateTypeParmDecl final : public TypeDecl, /// The default template argument, if any. using DefArgStorage = - DefaultArgStorage; + DefaultArgStorage; DefArgStorage DefaultArgument; TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, @@ -1225,13 +1225,9 @@ class TemplateTypeParmDecl final : public TypeDecl, bool hasDefaultArgument() const { return DefaultArgument.isSet(); } /// Retrieve the default argument, if any. - QualType getDefaultArgument() const { - return DefaultArgument.get()->getType(); - } - - /// Retrieves the default argument's source information, if any. - TypeSourceInfo *getDefaultArgumentInfo() const { - return DefaultArgument.get(); + const TemplateArgumentLoc &getDefaultArgument() const { + static const TemplateArgumentLoc NoneLoc; + return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc; } /// Retrieves the location of the default argument declaration. @@ -1244,9 +1240,8 @@ class TemplateTypeParmDecl final : public TypeDecl, } /// Set the default argument for this template parameter. - void setDefaultArgument(TypeSourceInfo *DefArg) { - DefaultArgument.set(DefArg); - } + void setDefaultArgument(const ASTContext &C, + const TemplateArgumentLoc &DefArg); /// Set that this default argument was inherited from another /// parameter. @@ -1365,7 +1360,8 @@ class NonTypeTemplateParmDecl final /// The default template argument, if any, and whether or not /// it was inherited. - using DefArgStorage = DefaultArgStorage; + using DefArgStorage = + DefaultArgStorage; DefArgStorage DefaultArgument; // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index @@ -1435,7 +1431,10 @@ class NonTypeTemplateParmDecl final bool hasDefaultArgument() const { return DefaultArgument.isSet(); } /// Retrieve the default argument, if any. - Expr *getDefaultArgument() const { return DefaultArgument.get(); } + const TemplateArgumentLoc &getDefaultArgument() const { + static const TemplateArgumentLoc NoneLoc; + return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc; + } /// Retrieve the location of the default argument, if any. SourceLocation getDefaultArgumentLoc() const; @@ -1449,7 +1448,8 @@ class NonTypeTemplateParmDecl final /// Set the default argument for this template parameter, and /// whether that default argument was inherited from another /// declaration. - void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); } + void setDefaultArgument(const ASTContext &C, + const TemplateArgumentLoc &DefArg); void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm) { DefaultArgument.setInherited(C, Parm); diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 607a2b9d65367..28ff8c44bd256 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -677,6 +677,35 @@ class OpenACCCreateClause final ArrayRef VarList, SourceLocation EndLoc); }; +class OpenACCReductionClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + OpenACCReductionOperator Op; + + OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + OpenACCReductionOperator Operator, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Reduction, BeginLoc, + LParenLoc, EndLoc), + Op(Operator) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Reduction; + } + + static OpenACCReductionClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + OpenACCReductionOperator Operator, ArrayRef VarList, + SourceLocation EndLoc); + + OpenACCReductionOperator getReductionOp() const { return Op; } +}; + template class OpenACCClauseVisitor { Impl &getDerived() { return static_cast(*this); } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index f5cefedb07e0e..4bbb4380cdd7f 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -30,6 +30,7 @@ #include "clang/AST/ExprOpenMP.h" #include "clang/AST/LambdaCapture.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenACCClause.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" @@ -510,6 +511,7 @@ template class RecursiveASTVisitor { bool TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S); bool VisitOpenACCClauseList(ArrayRef); + bool VisitOpenACCClause(const OpenACCClause *); }; template @@ -1960,7 +1962,7 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); TRY_TO(TraverseTemplateTypeParamDeclConstraints(D)); if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc())); + TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); }) DEF_TRAVERSE_DECL(TypedefDecl, { @@ -2320,7 +2322,7 @@ DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, { // A non-type template parameter, e.g. "S" in template class Foo ... TRY_TO(TraverseDeclaratorHelper(D)); if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - TRY_TO(TraverseStmt(D->getDefaultArgument())); + TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); }) DEF_TRAVERSE_DECL(ParmVarDecl, { @@ -3967,9 +3969,26 @@ bool RecursiveASTVisitor::TraverseOpenACCAssociatedStmtConstruct( return true; } +template +bool RecursiveASTVisitor::VisitOpenACCClause(const OpenACCClause *C) { + for (const Stmt *Child : C->children()) + TRY_TO(TraverseStmt(const_cast(Child))); + return true; +} + template bool RecursiveASTVisitor::VisitOpenACCClauseList( - ArrayRef) { + ArrayRef Clauses) { + + for (const auto *C : Clauses) + TRY_TO(VisitOpenACCClause(C)); +// if (const auto *WithCond = dyn_cast(C); +// WithCond && WIthCond->hasConditionExpr()) { +// TRY_TO(TraverseStmt(WithCond->getConditionExpr()); +// } else if (const auto * +// } +// OpenACCClauseWithCondition::getConditionExpr/hasConditionExpr +//OpenACCClauseWithExprs::children (might be null?) // TODO OpenACC: When we have Clauses with expressions, we should visit them // here. return true; diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index da3834f19ca04..263b632df23ce 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2515,6 +2515,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isRecordType() const; bool isClassType() const; bool isStructureType() const; + bool isStructureTypeWithFlexibleArrayMember() const; bool isObjCBoxableRecordType() const; bool isInterfaceType() const; bool isStructureOrClassType() const; @@ -2523,6 +2524,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. bool isExtVectorBoolType() const; // Extended vector type with bool element. + bool isSubscriptableVectorType() const; bool isMatrixType() const; // Matrix type. bool isConstantMatrixType() const; // Constant matrix type. bool isDependentAddressSpaceType() const; // value-dependent address space qualifier @@ -7729,6 +7731,10 @@ inline bool Type::isExtVectorBoolType() const { return cast(CanonicalType)->getElementType()->isBooleanType(); } +inline bool Type::isSubscriptableVectorType() const { + return isVectorType() || isSveVLSBuiltinType(); +} + inline bool Type::isMatrixType() const { return isa(CanonicalType); } diff --git a/clang/include/clang/Analysis/FlowSensitive/CNFFormula.h b/clang/include/clang/Analysis/FlowSensitive/CNFFormula.h new file mode 100644 index 0000000000000..fb13e774c67fe --- /dev/null +++ b/clang/include/clang/Analysis/FlowSensitive/CNFFormula.h @@ -0,0 +1,179 @@ +//===- CNFFormula.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A representation of a boolean formula in 3-CNF. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CNFFORMULA_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CNFFORMULA_H + +#include +#include + +#include "clang/Analysis/FlowSensitive/Formula.h" + +namespace clang { +namespace dataflow { + +/// Boolean variables are represented as positive integers. +using Variable = uint32_t; + +/// A null boolean variable is used as a placeholder in various data structures +/// and algorithms. +constexpr Variable NullVar = 0; + +/// Literals are represented as positive integers. Specifically, for a boolean +/// variable `V` that is represented as the positive integer `I`, the positive +/// literal `V` is represented as the integer `2*I` and the negative literal +/// `!V` is represented as the integer `2*I+1`. +using Literal = uint32_t; + +/// A null literal is used as a placeholder in various data structures and +/// algorithms. +constexpr Literal NullLit = 0; + +/// Clause identifiers are represented as positive integers. +using ClauseID = uint32_t; + +/// A null clause identifier is used as a placeholder in various data structures +/// and algorithms. +constexpr ClauseID NullClause = 0; + +/// Returns the positive literal `V`. +inline constexpr Literal posLit(Variable V) { return 2 * V; } + +/// Returns the negative literal `!V`. +inline constexpr Literal negLit(Variable V) { return 2 * V + 1; } + +/// Returns whether `L` is a positive literal. +inline constexpr bool isPosLit(Literal L) { return 0 == (L & 1); } + +/// Returns whether `L` is a negative literal. +inline constexpr bool isNegLit(Literal L) { return 1 == (L & 1); } + +/// Returns the negated literal `!L`. +inline constexpr Literal notLit(Literal L) { return L ^ 1; } + +/// Returns the variable of `L`. +inline constexpr Variable var(Literal L) { return L >> 1; } + +/// A boolean formula in 3-CNF (conjunctive normal form with at most 3 literals +/// per clause). +class CNFFormula { + /// `LargestVar` is equal to the largest positive integer that represents a + /// variable in the formula. + const Variable LargestVar; + + /// Literals of all clauses in the formula. + /// + /// The element at index 0 stands for the literal in the null clause. It is + /// set to 0 and isn't used. Literals of clauses in the formula start from the + /// element at index 1. + /// + /// For example, for the formula `(L1 v L2) ^ (L2 v L3 v L4)` the elements of + /// `Clauses` will be `[0, L1, L2, L2, L3, L4]`. + std::vector Clauses; + + /// Start indices of clauses of the formula in `Clauses`. + /// + /// The element at index 0 stands for the start index of the null clause. It + /// is set to 0 and isn't used. Start indices of clauses in the formula start + /// from the element at index 1. + /// + /// For example, for the formula `(L1 v L2) ^ (L2 v L3 v L4)` the elements of + /// `ClauseStarts` will be `[0, 1, 3]`. Note that the literals of the first + /// clause always start at index 1. The start index for the literals of the + /// second clause depends on the size of the first clause and so on. + std::vector ClauseStarts; + + /// Indicates that we already know the formula is unsatisfiable. + /// During construction, we catch simple cases of conflicting unit-clauses. + bool KnownContradictory; + +public: + explicit CNFFormula(Variable LargestVar); + + /// Adds the `L1 v ... v Ln` clause to the formula. + /// Requirements: + /// + /// `Li` must not be `NullLit`. + /// + /// All literals in the input that are not `NullLit` must be distinct. + void addClause(ArrayRef lits); + + /// Returns whether the formula is known to be contradictory. + /// This is the case if any of the clauses is empty. + bool knownContradictory() const { return KnownContradictory; } + + /// Returns the largest variable in the formula. + Variable largestVar() const { return LargestVar; } + + /// Returns the number of clauses in the formula. + /// Valid clause IDs are in the range [1, `numClauses()`]. + ClauseID numClauses() const { return ClauseStarts.size() - 1; } + + /// Returns the number of literals in clause `C`. + size_t clauseSize(ClauseID C) const { + return C == ClauseStarts.size() - 1 ? Clauses.size() - ClauseStarts[C] + : ClauseStarts[C + 1] - ClauseStarts[C]; + } + + /// Returns the literals of clause `C`. + /// If `knownContradictory()` is false, each clause has at least one literal. + llvm::ArrayRef clauseLiterals(ClauseID C) const { + size_t S = clauseSize(C); + if (S == 0) + return llvm::ArrayRef(); + return llvm::ArrayRef(&Clauses[ClauseStarts[C]], S); + } + + /// An iterator over all literals of all clauses in the formula. + /// The iterator allows mutation of the literal through the `*` operator. + /// This is to support solvers that mutate the formula during solving. + class Iterator { + friend class CNFFormula; + CNFFormula *CNF; + size_t Idx; + Iterator(CNFFormula *CNF, size_t Idx) : CNF(CNF), Idx(Idx) {} + + public: + Iterator(const Iterator &) = default; + Iterator &operator=(const Iterator &) = default; + + Iterator &operator++() { + ++Idx; + assert(Idx < CNF->Clauses.size() && "Iterator out of bounds"); + return *this; + } + + Iterator next() const { + Iterator I = *this; + ++I; + return I; + } + + Literal &operator*() const { return CNF->Clauses[Idx]; } + }; + friend class Iterator; + + /// Returns an iterator to the first literal of clause `C`. + Iterator startOfClause(ClauseID C) { return Iterator(this, ClauseStarts[C]); } +}; + +/// Converts the conjunction of `Vals` into a formula in conjunctive normal +/// form where each clause has at least one and at most three literals. +/// `Atomics` is populated with a mapping from `Variables` to the corresponding +/// `Atom`s for atomic booleans in the input formulas. +CNFFormula buildCNF(const llvm::ArrayRef &Formulas, + llvm::DenseMap &Atomics); + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CNFFORMULA_H diff --git a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h index b5cd7aa10fd7d..d74380b78e935 100644 --- a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h +++ b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h @@ -17,16 +17,17 @@ #include "clang/Analysis/FlowSensitive/Formula.h" #include "clang/Analysis/FlowSensitive/Solver.h" #include "llvm/ADT/ArrayRef.h" -#include namespace clang { namespace dataflow { /// A SAT solver that is an implementation of Algorithm D from Knuth's The Art /// of Computer Programming Volume 4: Satisfiability, Fascicle 6. It is based on -/// the Davis-Putnam-Logemann-Loveland (DPLL) algorithm, keeps references to a -/// single "watched" literal per clause, and uses a set of "active" variables +/// the Davis-Putnam-Logemann-Loveland (DPLL) algorithm [1], keeps references to +/// a single "watched" literal per clause, and uses a set of "active" variables /// for unit propagation. +// +// [1] https://en.wikipedia.org/wiki/DPLL_algorithm class WatchedLiteralsSolver : public Solver { // Count of the iterations of the main loop of the solver. This spans *all* // calls to the underlying solver across the life of this object. It is diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 7008bea483c87..e59cccccdd369 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1640,10 +1640,11 @@ def Unlikely : StmtAttr { def : MutualExclusions<[Likely, Unlikely]>; def CXXAssume : StmtAttr { - let Spellings = [CXX11<"", "assume", 202207>]; + let Spellings = [CXX11<"", "assume", 202207>, Clang<"assume">]; let Subjects = SubjectList<[NullStmt], ErrorDiag, "empty statements">; let Args = [ExprArgument<"Assumption">]; let Documentation = [CXXAssumeDocs]; + let HasCustomParsing = 1; } def NoMerge : DeclOrStmtAttr { @@ -2256,7 +2257,8 @@ def TypeNullUnspecified : TypeAttr { def CountedBy : DeclOrTypeAttr { let Spellings = [Clang<"counted_by">]; let Subjects = SubjectList<[Field], ErrorDiag>; - let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel">]; + let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel", 1>]; + let LateParsed = LateAttrParseExperimentalExt; let ParseArgumentsAsUnevaluated = 1; let Documentation = [CountedByDocs]; let LangOpts = [COnly]; @@ -4255,7 +4257,7 @@ def OMPDeclareVariant : InheritableAttr { } def OMPAssume : InheritableAttr { - let Spellings = [Clang<"assume">, CXX11<"omp", "assume">]; + let Spellings = [CXX11<"omp", "assume">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let InheritEvenIfAlreadyPresent = 1; let Documentation = [OMPAssumeDocs]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 54197d588eb45..a313e811c9d21 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -2027,9 +2027,6 @@ Different optimisers are likely to react differently to the presence of this attribute; in some cases, adding ``assume`` may affect performance negatively. It should be used with parsimony and care. -Note that `clang::assume` is a different attribute. Always write ``assume`` -without a namespace if you intend to use the standard C++ attribute. - Example: .. code-block:: c++ @@ -4740,7 +4737,7 @@ def OMPAssumeDocs : Documentation { let Category = DocCatFunction; let Heading = "assume"; let Content = [{ -Clang supports the ``__attribute__((assume("assumption")))`` attribute to +Clang supports the ``[[omp::assume("assumption")]]`` attribute to provide additional information to the optimizer. The string-literal, here "assumption", will be attached to the function declaration such that later analysis and optimization passes can assume the "assumption" to hold. @@ -4752,7 +4749,7 @@ A function can have multiple assume attributes and they propagate from prior declarations to later definitions. Multiple assumptions are aggregated into a single comma separated string. Thus, one can provide multiple assumptions via a comma separated string, i.a., -``__attribute__((assume("assumption1,assumption2")))``. +``[[omp::assume("assumption1,assumption2")]]``. While LLVM plugins might provide more assumption strings, the default LLVM optimization passes are aware of the following assumptions: diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index cf8711c6eaee3..5f53c98167dfb 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -290,7 +290,7 @@ TARGET_HEADER_BUILTIN(_CountLeadingZeros64, "UiULLi", "nh", INTRIN_H, ALL_MS_LAN TARGET_HEADER_BUILTIN(_CountOneBits, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__prefetch, "vv*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__prefetch, "vvC*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") #undef BUILTIN #undef LANGBUILTIN diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 3e21a2fe2ac6b..433c7795325f0 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -68,7 +68,7 @@ BUILTIN(__builtin_amdgcn_sched_group_barrier, "vIiIiIi", "n") BUILTIN(__builtin_amdgcn_iglp_opt, "vIi", "n") BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n") BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n") -BUILTIN(__builtin_amdgcn_fence, "vUicC*", "n") +BUILTIN(__builtin_amdgcn_fence, "vUicC*.", "n") BUILTIN(__builtin_amdgcn_groupstaticsize, "Ui", "n") BUILTIN(__builtin_amdgcn_wavefrontsize, "Ui", "nc") @@ -240,6 +240,7 @@ TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_v2bf16, "V2sV2s*0V2s", "t", "at TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2bf16, "V2sV2s*1V2s", "t", "atomic-global-pk-add-bf16-inst") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2bf16, "V2sV2s*3V2s", "t", "atomic-ds-pk-add-16-insts") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2f16, "V2hV2h*3V2h", "t", "atomic-ds-pk-add-16-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3UiiUi", "t", "gfx940-insts") //===----------------------------------------------------------------------===// // Deep learning builtins. diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index 8645cff1e8679..fd8c1b480d6da 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -193,6 +193,8 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f" // Half-Precision (fp16) TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision") TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision") +TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision") // Reference Types builtins // Some builtins are custom type-checked - see 't' as part of the third argument, diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index eafcc219c1096..7074479786b97 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -832,23 +832,11 @@ TARGET_BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512") -TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512") - TARGET_BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512") -TARGET_BUILTIN(__builtin_ia32_rcp28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rcp28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512") - TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f,evex512") @@ -960,15 +948,6 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8OiV8OiIi", "nV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8OiV8iIi", "nV:512:", "avx512f,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8OivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8OivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf,evex512") - TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw") diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 0738f43ca555c..1e44bc4ad09b6 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -361,9 +361,6 @@ def warn_invalid_feature_combination : Warning< def warn_target_unrecognized_env : Warning< "mismatch between architecture and environment in target triple '%0'; did you mean '%1'?">, InGroup; -def warn_knl_knm_isa_support_removed : Warning< - "KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.">, - InGroup>; def err_target_unsupported_abi_with_fpu : Error< "'%0' ABI is not supported with FPU">; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 9d97a75f696f6..773b234cd68fe 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -58,7 +58,7 @@ def warn_drv_avr_stdlib_not_linked: Warning< def err_drv_cuda_bad_gpu_arch : Error<"unsupported CUDA gpu architecture: %0">; def err_drv_offload_bad_gpu_arch : Error<"unsupported %0 gpu architecture: %1">; def err_drv_offload_missing_gpu_arch : Error< - "Must pass in an explicit %0 gpu architecture to '%1'">; + "must pass in an explicit %0 gpu architecture to '%1'">; def err_drv_no_cuda_installation : Error< "cannot find CUDA installation; provide its path via '--cuda-path', or pass " "'-nocudainc' to build without CUDA includes">; @@ -90,8 +90,8 @@ def err_drv_no_hipspv_device_lib : Error< "'--hip-path' or '--hip-device-lib-path', or pass '-nogpulib' to build " "without HIP device library">; def err_drv_hipspv_no_hip_path : Error< - "'--hip-path' must be specified when offloading to " - "SPIR-V%select{| unless %1 is given}0.">; + "'--hip-path' must be specified when offloading to SPIR-V unless '-nogpuinc' " + "is given">; // TODO: Remove when COV6 is fully supported by ROCm. def warn_drv_amdgpu_cov6: Warning< @@ -137,13 +137,13 @@ def warn_drv_unsupported_option_for_flang : Warning< "the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">, InGroup; def warn_drv_unsupported_diag_option_for_flang : Warning< - "The warning option '-%0' is not supported">, + "the warning option '-%0' is not supported">, InGroup; def warn_drv_unsupported_option_for_processor : Warning< "ignoring '%0' option as it is not currently supported for processor '%1'">, InGroup; def warn_drv_unsupported_openmp_library : Warning< - "The library '%0=%1' is not supported, openmp is not be enabled">, + "the library '%0=%1' is not supported, OpenMP will not be enabled">, InGroup; def err_drv_invalid_thread_model_for_target : Error< @@ -356,7 +356,7 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error< "compatible with offloading; e.g., '-fopenmp=libomp' or '-fopenmp=libiomp5'">; def err_drv_failed_to_deduce_target_from_arch : Error< "failed to deduce triple for target architecture '%0'; specify the triple " - "using '-fopenmp-targets' and '-Xopenmp-target' instead.">; + "using '-fopenmp-targets' and '-Xopenmp-target' instead">; def err_drv_omp_offload_target_missingbcruntime : Error< "no library '%0' found in the default clang lib directory or in LIBRARY_PATH" "; use '--libomptarget-%1-bc-path' to specify %1 bitcode library">; @@ -515,14 +515,6 @@ def err_analyzer_checker_incompatible_analyzer_option : Error< def err_analyzer_not_built_with_z3 : Error< "analyzer constraint manager 'z3' is only available if LLVM was built with " "-DLLVM_ENABLE_Z3_SOLVER=ON">; -def warn_analyzer_deprecated_option : Warning< - "analyzer option '%0' is deprecated. This flag will be removed in %1, and " - "passing this option will be an error.">, - InGroup; -def warn_analyzer_deprecated_option_with_alternative : Warning< - "analyzer option '%0' is deprecated. This flag will be removed in %1, and " - "passing this option will be an error. Use '%2' instead.">, - InGroup; def warn_drv_needs_hvx : Warning< "%0 requires HVX, use -mhvx/-mhvx= to enable it">, @@ -555,10 +547,12 @@ def err_drv_extract_api_wrong_kind : Error< "in api extraction; use '-x %2' to override">; def err_drv_missing_symbol_graph_dir: Error< - "Must provide a symbol graph output directory using --symbol-graph-dir=">; + "must provide a symbol graph output directory using " + "'--symbol-graph-dir='">; def err_drv_unexpected_symbol_graph_output : Error< - "Unexpected output symbol graph '%1'; please provide --symbol-graph-dir= instead">; + "unexpected output symbol graph '%1'; please provide " + "'--symbol-graph-dir=' instead">; def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">, InGroup>; @@ -599,9 +593,6 @@ def warn_drv_unsupported_gpopt : Warning< "ignoring '-mgpopt' option as it cannot be used with %select{|the implicit" " usage of }0-mabicalls">, InGroup; -def warn_drv_unsupported_tocdata: Warning< - "ignoring '-mtocdata' as it is only supported for -mcmodel=small">, - InGroup; def warn_drv_unsupported_sdata : Warning< "ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">, InGroup; @@ -770,19 +761,19 @@ def err_drv_hlsl_16bit_types_unsupported: Error< "'%0' option requires target HLSL Version >= 2018%select{| and shader model >= 6.2}1, but HLSL Version is '%2'%select{| and shader model is '%3'}1">; def err_drv_hlsl_bad_shader_unsupported : Error< "%select{shader model|Vulkan environment|shader stage}0 '%1' in target '%2' is invalid for HLSL code generation">; -def warn_drv_dxc_missing_dxv : Warning<"dxv not found. " - "Resulting DXIL will not be validated or signed for use in release environments.">, - InGroup; +def warn_drv_dxc_missing_dxv : Warning< + "dxv not found; resulting DXIL will not be validated or signed for use in " + "release environment">, InGroup; def err_drv_invalid_range_dxil_validator_version : Error< - "invalid validator version : %0\n" - "Validator version must be less than or equal to current internal version.">; + "invalid validator version : %0; validator version must be less than or " + "equal to current internal version">; def err_drv_invalid_format_dxil_validator_version : Error< - "invalid validator version : %0\n" - "Format of validator version is \".\" (ex:\"1.4\").">; + "invalid validator version : %0; format of validator version is " + "\".\" (ex:\"1.4\")">; def err_drv_invalid_empty_dxil_validator_version : Error< - "invalid validator version : %0\n" - "If validator major version is 0, minor version must also be 0.">; + "invalid validator version : %0; if validator major version is 0, minor " + "version must also be 0">; def warn_drv_sarif_format_unstable : Warning< "diagnostic formatting in SARIF mode is currently unstable">, @@ -796,12 +787,10 @@ def warn_drv_loongarch_conflicting_implied_val : Warning< InGroup; def err_drv_loongarch_invalid_mfpu_EQ : Error< "invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">; -def err_drv_loongarch_wrong_fpu_width_for_lsx : Error< - "wrong fpu width; LSX depends on 64-bit FPU.">; -def err_drv_loongarch_wrong_fpu_width_for_lasx : Error< - "wrong fpu width; LASX depends on 64-bit FPU.">; +def err_drv_loongarch_wrong_fpu_width : Error< + "wrong fpu width; %select{LSX|LASX}0 depends on 64-bit FPU">; def err_drv_loongarch_invalid_simd_option_combination : Error< - "invalid option combination; LASX depends on LSX.">; + "invalid option combination; LASX depends on LSX">; def err_drv_expand_response_file : Error< "failed to expand response file: %0">; @@ -813,9 +802,9 @@ def note_drv_available_multilibs : Note< "available multilibs are:%0">; def warn_android_unversioned_fallback : Warning< - "Using unversioned Android target directory %0 for target %1. Unversioned" - " directories will not be used in Clang 19. Provide a versioned directory" - " for the target version or lower instead.">, + "using unversioned Android target directory %0 for target %1; unversioned " + "directories will not be used in Clang 19 -- provide a versioned directory " + "for the target version or lower instead">, InGroup>; def err_drv_triple_version_invalid : Error< diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index e456ec2cac461..85c32e55bdab3 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -71,14 +71,14 @@ def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo, InGroup; def remark_fe_backend_optimization_remark_analysis_fpcommute : Remark<"%0; " "allow reordering by specifying '#pragma clang loop vectorize(enable)' " - "before the loop or by providing the compiler option '-ffast-math'.">, + "before the loop or by providing the compiler option '-ffast-math'">, BackendInfo, InGroup; def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; " "allow reordering by specifying '#pragma clang loop vectorize(enable)' " - "before the loop. If the arrays will always be independent specify " + "before the loop; if the arrays will always be independent, specify " "'#pragma clang loop vectorize(assume_safety)' before the loop or provide " - "the '__restrict__' qualifier with the independent array arguments. " - "Erroneous results will occur if these options are incorrectly applied!">, + "the '__restrict__' qualifier with the independent array arguments -- " + "erroneous results will occur if these options are incorrectly applied">, BackendInfo, InGroup; def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo, @@ -152,8 +152,8 @@ def warn_fe_serialized_diag_merge_failure : Warning< def warn_fe_serialized_diag_failure : Warning< "unable to open file %0 for serializing diagnostics (%1)">, InGroup; -def warn_fe_serialized_diag_failure_during_finalisation : Warning< - "Received warning after diagnostic serialization teardown was underway: %0">, +def warn_fe_serialized_diag_failure_during_finalization : Warning< + "received warning after diagnostic serialization teardown was underway: %0">, InGroup; def err_verify_missing_line : Error< @@ -337,7 +337,7 @@ def warn_atomic_op_oversized : Warning< InGroup; def warn_sync_op_misaligned : Warning< - "__sync builtin operation MUST have natural alignment (consider using __atomic).">, + "__sync builtin operation must have natural alignment (consider using __atomic)">, InGroup; def warn_alias_with_section : Warning< @@ -359,17 +359,16 @@ def warn_profile_data_unprofiled : Warning< "no profile data available for file \"%0\"">, InGroup; def warn_profile_data_misexpect : Warning< - "Potential performance regression from use of __builtin_expect(): " - "Annotation was correct on %0 of profiled executions.">, - BackendInfo, - InGroup; + "potential performance regression from use of __builtin_expect(): " + "annotation was correct on %0 of profiled executions">, + BackendInfo, InGroup; } // end of instrumentation issue category def err_extract_api_ignores_file_not_found : Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal; def warn_missing_symbol_graph_dir : Warning< - "Missing symbol graph output directory, defaulting to working directory">, + "missing symbol graph output directory, defaulting to working directory">, InGroup; def err_ast_action_on_llvm_ir : Error< diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 4cb4f3d999f7a..6b595a3567932 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -15,8 +15,6 @@ def Implicit : DiagGroup<"implicit", [ ImplicitInt ]>; -def DeprecatedStaticAnalyzerFlag : DiagGroup<"deprecated-static-analyzer-flag">; - // Empty DiagGroups are recognized by clang but ignored. def ODR : DiagGroup<"odr">; def : DiagGroup<"abi">; @@ -1447,6 +1445,10 @@ def FunctionMultiVersioning def NoDeref : DiagGroup<"noderef">; +// -fbounds-safety and bounds annotation related warnings +def BoundsSafetyCountedByEltTyUnknownSize : + DiagGroup<"bounds-safety-counted-by-elt-type-unknown-size">; + // A group for cross translation unit static analysis related warnings. def CrossTU : DiagGroup<"ctu">; diff --git a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td index 944b2a38b6e96..cdf27247602f2 100644 --- a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td +++ b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td @@ -59,8 +59,8 @@ def err_platform_mismatch : Error<"platform does not match: '%0' (provided) vs ' def err_install_name_mismatch : Error<"install_name does not match: '%0' (provided) vs '%1' (found)">; def err_current_version_mismatch : Error<"current_version does not match: '%0' (provided) vs '%1' (found)">; def err_compatibility_version_mismatch : Error<"compatibility_version does not match: '%0' (provided) vs '%1' (found)">; -def err_appextension_safe_mismatch : Error<"ApplicationExtensionSafe flag does not match: '%0' (provided) vs '%1' (found)">; -def err_shared_cache_eligiblity_mismatch : Error<"NotForDyldSharedCache flag does not match: '%0' (provided) vs '%1' (found)">; +def err_appextension_safe_mismatch : Error<"the ApplicationExtensionSafe flag does not match: '%0' (provided) vs '%1' (found)">; +def err_shared_cache_eligiblity_mismatch : Error<"the NotForDyldSharedCache flag does not match: '%0' (provided) vs '%1' (found)">; def err_no_twolevel_namespace : Error<"flat namespace libraries are not supported">; def err_parent_umbrella_missing: Error<"parent umbrella missing from %0: '%1'">; def err_parent_umbrella_mismatch : Error<"parent umbrella does not match: '%0' (provided) vs '%1' (found)">; diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index ad6bacfb118d4..5a4551a96ca4e 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -991,5 +991,5 @@ def err_pp_unclosed_pragma_unsafe_buffer_usage : Error<"'#pragma unsafe_buffer_usage' was not ended">; def err_pp_pragma_unsafe_buffer_usage_syntax : -Error<"Expected 'begin' or 'end'">; +Error<"expected 'begin' or 'end'">; } diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 46656fc66044d..f8328be5890dd 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1117,7 +1117,7 @@ def err_availability_expected_environment : Error< // objc_bridge_related attribute def err_objcbridge_related_expected_related_class : Error< - "expected a related ObjectiveC class name, e.g., 'NSColor'">; + "expected a related Objective-C class name, e.g., 'NSColor'">; def err_objcbridge_related_selector_name : Error< "expected a class method selector with single argument, e.g., 'colorWithCGColor:'">; @@ -1345,8 +1345,8 @@ def note_pragma_attribute_namespace_on_attribute : Note< "omit the namespace to add attributes to the most-recently" " pushed attribute group">; def warn_no_support_for_eval_method_source_on_m32 : Warning< - "Setting the floating point evaluation method to `source` on a target" - " without SSE is not supported.">, InGroup; + "setting the floating point evaluation method to `source` on a target " + "without SSE is not supported">, InGroup; // - #pragma __debug def warn_pragma_debug_dependent_argument : Warning< "%select{value|type}0-dependent expression passed as an argument to debug " diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e3c65cba4886a..f15cba63624ea 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -310,7 +310,7 @@ def err_invalid_vector_long_double_decl_spec : Error< def err_invalid_vector_complex_decl_spec : Error< "cannot use '_Complex' with '__vector'">; def warn_vector_long_decl_spec_combination : Warning< - "Use of 'long' with '__vector' is deprecated">, InGroup; + "use of 'long' with '__vector' is deprecated">, InGroup; def err_redeclaration_different_type : Error< "redeclaration of %0 with a different type%diff{: $ vs $|}1,2">; @@ -754,7 +754,7 @@ def note_include_header_or_declare : Note< def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">; def warn_implicit_decl_no_jmp_buf : Warning<"declaration of built-in function '%0' requires the declaration" - " of the 'jmp_buf' type, commonly provided in the header .">, + " of the 'jmp_buf' type, commonly provided in the header ">, InGroup>; def warn_implicit_decl_requires_sysheader : Warning< "declaration of built-in function '%1' requires inclusion of the header <%0>">, @@ -855,7 +855,7 @@ def note_strncat_wrong_size : Note< "the terminating null byte">; def warn_assume_side_effects : Warning< - "the argument to %0 has side effects that will be discarded">, + "assumption is ignored because it contains (potential) side-effects">, InGroup>; def warn_omp_assume_attribute_string_unknown : Warning< "unknown assumption string '%0'; attribute is potentially ignored">, @@ -3197,7 +3197,7 @@ def err_attribute_bad_sve_vector_size : Error< "'-msve-vector-bits' ('%1')">; def err_attribute_arm_feature_sve_bits_unsupported : Error< "%0 is only supported when '-msve-vector-bits=' is specified with a " - "value of 128, 256, 512, 1024 or 2048.">; + "value of 128, 256, 512, 1024 or 2048">; def warn_attribute_arm_sm_incompat_builtin : Warning< "builtin call has undefined behaviour when called from a %0 function">, InGroup>; @@ -3975,7 +3975,7 @@ def warn_acquired_before : Warning< "%0 '%1' must be acquired before '%2'">, InGroup, DefaultIgnore; def warn_acquired_before_after_cycle : Warning< - "Cycle in acquired_before/after dependencies, starting with '%0'">, + "cycle in acquired_before/after dependencies, starting with '%0'">, InGroup, DefaultIgnore; @@ -4526,7 +4526,7 @@ def err_objc_attr_typedef_not_void_pointer : Error< def err_objc_cf_bridged_not_interface : Error< "CF object of type %0 is bridged to %1, which is not an Objective-C class">; def err_objc_ns_bridged_invalid_cfobject : Error< - "ObjectiveC object of type %0 is bridged to %1, which is not valid CF object">; + "Objective-C object of type %0 is bridged to %1, which is not valid CF object">; def warn_objc_invalid_bridge : Warning< "%0 bridges to %1, not %2">, InGroup; def warn_objc_invalid_bridge_to_cf : Warning< @@ -6544,8 +6544,10 @@ def warn_superclass_variable_sized_type_not_at_end : Warning< def err_flexible_array_count_not_in_same_struct : Error< "'counted_by' field %0 isn't within the same struct as the flexible array">; -def err_counted_by_attr_not_on_flexible_array_member : Error< - "'counted_by' only applies to C99 flexible array members">; +def err_counted_by_attr_not_on_ptr_or_flexible_array_member : Error< + "'counted_by' only applies to pointers or C99 flexible array members">; +def err_counted_by_attr_on_array_not_flexible_array_member : Error< + "'counted_by' on arrays only applies to C99 flexible array members">; def err_counted_by_attr_refer_to_itself : Error< "'counted_by' cannot refer to the flexible array member %0">; def err_counted_by_must_be_in_structure : Error< @@ -6560,6 +6562,23 @@ def err_counted_by_attr_refer_to_union : Error< "'counted_by' argument cannot refer to a union member">; def note_flexible_array_counted_by_attr_field : Note< "field %0 declared here">; +def err_counted_by_attr_pointee_unknown_size : Error< + "'counted_by' %select{cannot|should not}3 be applied to %select{" + "a pointer with pointee|" // pointer + "an array with element}0" // array + " of unknown size because %1 is %select{" + "an incomplete type|" // CountedByInvalidPointeeTypeKind::INCOMPLETE + "a sizeless type|" // CountedByInvalidPointeeTypeKind::SIZELESS + "a function type|" // CountedByInvalidPointeeTypeKind::FUNCTION + // CountedByInvalidPointeeTypeKind::FLEXIBLE_ARRAY_MEMBER + "a struct type with a flexible array member" + "%select{|. This will be an error in a future compiler version}3" + "" + "}2">; + +def warn_counted_by_attr_elt_type_unknown_size : + Warning, + InGroup; let CategoryName = "ARC Semantic Issue" in { @@ -7525,6 +7544,11 @@ def err_explicit_object_parameter_mutable: Error< def err_invalid_explicit_object_type_in_lambda: Error< "invalid explicit object parameter type %0 in lambda with capture; " "the type must be the same as, or derived from, the lambda">; +def err_explicit_object_lambda_ambiguous_base : Error< + "lambda %0 is inaccessible due to ambiguity:%1">; +def err_explicit_object_lambda_inaccessible_base : Error< + "invalid explicit object parameter type %0 in lambda with capture; " + "the type must derive publicly from the lambda">; def err_ref_qualifier_overload : Error< "cannot overload a member function %select{without a ref-qualifier|with " @@ -7997,15 +8021,15 @@ def warn_deprecated_volatile_structured_binding : Warning< InGroup; def warn_deprecated_altivec_src_compat : Warning< - "Current handling of vector bool and vector pixel types in this context are " - "deprecated. The default behaviour will soon change to that implied by the " + "current handling of vector bool and vector pixel types in this context are " + "deprecated; the default behaviour will soon change to that implied by the " "'-altivec-compat=xl' option">, InGroup>; def warn_deprecated_lax_vec_conv_all : Warning< - "Implicit conversion between vector types ('%0' and '%1') is deprecated. " - "In the future, the behavior implied by '-fno-lax-vector-conversions' " - "will be the default.">, + "implicit conversion between vector types ('%0' and '%1') is deprecated; " + "in the future, the behavior implied by '-fno-lax-vector-conversions' " + "will be the default">, InGroup>; def err_catch_incomplete_ptr : Error< @@ -8836,8 +8860,10 @@ def err_builtin_fn_use : Error<"builtin functions must be directly called">; def warn_call_wrong_number_of_arguments : Warning< "too %select{few|many}0 arguments in call to %1">; + def err_atomic_builtin_must_be_pointer : Error< - "address argument to atomic builtin must be a pointer (%0 invalid)">; + "address argument to atomic builtin must be a pointer %select{|to a non-zero-sized object }1(%0 invalid)">; + def err_atomic_builtin_must_be_pointer_intptr : Error< "address argument to atomic builtin must be a pointer to integer or pointer" " (%0 invalid)">; @@ -8853,7 +8879,7 @@ def err_atomic_exclusive_builtin_pointer_size : Error< "address argument to load or store exclusive builtin must be a pointer to" " 1,2,4 or 8 byte type (%0 invalid)">; def err_atomic_builtin_ext_int_size : Error< - "Atomic memory operand must have a power-of-two size">; + "atomic memory operand must have a power-of-two size">; def err_atomic_builtin_bit_int_prohibit : Error< "argument to atomic builtin of type '_BitInt' is not supported">; def err_atomic_op_needs_atomic : Error< @@ -8961,8 +8987,8 @@ def err_va_arg_in_device : Error< def err_alias_not_supported_on_nvptx : Error<"CUDA older than 10.0 does not support .alias">; def err_cuda_unattributed_constexpr_cannot_overload_device : Error< "constexpr function %0 without __host__ or __device__ attributes cannot " - "overload __device__ function with same signature. Add a __host__ " - "attribute, or build with -fno-cuda-host-device-constexpr.">; + "overload __device__ function with the same signature; add a __host__ " + "attribute, or build with -fno-cuda-host-device-constexpr">; def note_cuda_conflicting_device_function_declared_here : Note< "conflicting __device__ function declared here">; def err_cuda_device_exceptions : Error< @@ -8970,9 +8996,9 @@ def err_cuda_device_exceptions : Error< "%select{__device__|__global__|__host__|__host__ __device__}1 function">; def err_dynamic_var_init : Error< "dynamic initialization is not supported for " - "__device__, __constant__, __shared__, and __managed__ variables.">; + "__device__, __constant__, __shared__, and __managed__ variables">; def err_shared_var_init : Error< - "initialization is not supported for __shared__ variables.">; + "initialization is not supported for __shared__ variables">; def err_cuda_vla : Error< "cannot use variable-length arrays in " "%select{__device__|__global__|__host__|__host__ __device__}0 functions">; @@ -10056,12 +10082,6 @@ def warn_new_dangling_initializer_list : Warning< "the allocated initializer list}0 " "will be destroyed at the end of the full-expression">, InGroup; -def warn_unsupported_lifetime_extension : Warning< - "lifetime extension of " - "%select{temporary|backing array of initializer list}0 created " - "by aggregate initialization using a default member initializer " - "is not yet supported; lifetime of %select{temporary|backing array}0 " - "will end at the end of the full-expression">, InGroup; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -10237,9 +10257,6 @@ def err_fallthrough_attr_outside_switch : Error< def err_fallthrough_attr_invalid_placement : Error< "fallthrough annotation does not directly precede switch label">; -def err_assume_attr_args : Error< - "attribute '%0' requires a single expression argument">; - def warn_unreachable_default : Warning< "default label in switch which covers all enumeration values">, InGroup, DefaultIgnore; @@ -10365,12 +10382,12 @@ def err_shufflevector_argument_too_large : Error< "index for __builtin_shufflevector must be less than the total number " "of vector elements">; def err_shufflevector_minus_one_is_undefined_behavior_constexpr : Error< - "index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position %0 not permitted in a constexpr context.">; + "index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position %0 is not permitted in a constexpr context">; def err_convertvector_non_vector : Error< "first argument to __builtin_convertvector must be a vector">; def err_convertvector_constexpr_unsupported_vector_cast : Error< - "unsupported vector cast from %0 to %1 in a constant expression.">; + "unsupported vector cast from %0 to %1 in a constant expression">; def err_builtin_non_vector_type : Error< "%0 argument to %1 must be of vector type">; def err_convertvector_incompatible_vector : Error< @@ -10698,7 +10715,7 @@ def err_kernel_arg_address_space : Error< "pointer arguments to kernel functions must reside in '__global', " "'__constant' or '__local' address space">; def err_opencl_ext_vector_component_invalid_length : Error< - "vector component access has invalid length %0. Supported: 1,2,3,4,8,16.">; + "vector component access has invalid length %0; supported lengths are: 1,2,3,4,8,16">; def err_opencl_function_variable : Error< "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">; def err_opencl_addrspace_scope : Error< @@ -11146,12 +11163,12 @@ def err_omp_atomic_compare : Error< "the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}'," " '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}'," " 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type," - " and 'ordop' is one of '<' or '>'.">; + " and 'ordop' is one of '<' or '>'">; def err_omp_atomic_compare_capture : Error< "the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}'," " '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}'," " 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x', 'r', and 'v' are lvalue expressions with scalar type, 'expr', 'e', and 'd' are expressions with scalar type," - " and 'ordop' is one of '<' or '>'.">; + " and 'ordop' is one of '<' or '>'">; def note_omp_atomic_compare: Note< "%select{expected compound statement|expected exactly one expression statement|expected assignment statement|expected conditional operator|expect result value to be at false expression|" "expect binary operator in conditional expression|expect '<', '>' or '==' as order operator|expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'|" @@ -11317,7 +11334,7 @@ def err_omp_expected_int_param : Error< def err_omp_at_least_one_motion_clause_required : Error< "expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">; def err_omp_cannot_update_with_internal_linkage : Error< - "the host cannot update a declare target variable that is not externally visible.">; + "the host cannot update a declare target variable that is not externally visible">; def err_omp_usedeviceptr_not_a_pointer : Error< "expected pointer or reference to pointer in 'use_device_ptr' clause">; def err_omp_argument_type_isdeviceptr : Error < @@ -11338,10 +11355,10 @@ def err_omp_reduction_vla_unsupported : Error< def err_omp_linear_distribute_var_non_loop_iteration : Error< "only loop iteration variables are allowed in 'linear' clause in distribute directives">; def warn_omp_non_trivial_type_mapped : Warning< - "Type %0 is not trivially copyable and not guaranteed to be mapped correctly">, + "type %0 is not trivially copyable and not guaranteed to be mapped correctly">, InGroup; def err_omp_requires_clause_redeclaration : Error < - "Only one %0 clause can appear on a requires directive in a single translation unit">; + "only one %0 clause can appear on a requires directive in a single translation unit">; def note_omp_requires_previous_clause : Note < "%0 clause previously used here">; def err_omp_directive_before_requires : Error < @@ -11349,7 +11366,7 @@ def err_omp_directive_before_requires : Error < def note_omp_requires_encountered_directive : Note < "'%0' previously encountered here">; def err_omp_device_ancestor_without_requires_reverse_offload : Error < - "Device clause with ancestor device-modifier used without specifying 'requires reverse_offload'">; + "device clause with ancestor device-modifier used without specifying 'requires reverse_offload'">; def err_omp_invalid_scope : Error < "'#pragma omp %0' directive must appear only in file scope">; def note_omp_invalid_length_on_this_ptr_mapping : Note < @@ -11761,7 +11778,7 @@ def note_await_ready_no_bool_conversion : Note< "return type of 'await_ready' is required to be contextually convertible to 'bool'" >; def warn_coroutine_handle_address_invalid_return_type : Warning < - "return type of 'coroutine_handle<>::address should be 'void*' (have %0) in order to get capability with existing async C API.">, + "return type of 'coroutine_handle<>::address should be 'void*' (have %0) in order to get capability with existing async C API">, InGroup; def err_coroutine_promise_final_suspend_requires_nothrow : Error< "the expression 'co_await __promise.final_suspend()' is required to be non-throwing" @@ -11789,7 +11806,7 @@ def err_conflicting_aligned_options : Error < "conflicting option '-fcoro-aligned-allocation' and '-fno-aligned-allocation'" >; def err_coro_invalid_addr_of_label : Error< - "the GNU address of label extension is not allowed in coroutines." + "the GNU address of label extension is not allowed in coroutines" >; def err_coroutine_return_type : Error< "function returns a type %0 marked with [[clang::coro_return_type]] but is neither a coroutine nor a coroutine wrapper; " @@ -12343,7 +12360,8 @@ def err_acc_num_gangs_num_args "provided}0">; def err_acc_not_a_var_ref : Error<"OpenACC variable is not a valid variable name, sub-array, array " - "element, or composite variable member">; + "element,%select{| member of a composite variable,}0 or composite " + "variable member">; def err_acc_typecheck_subarray_value : Error<"OpenACC sub-array subscripted value is not an array or pointer">; def err_acc_subarray_function_type @@ -12374,5 +12392,22 @@ def note_acc_expected_pointer_var : Note<"expected variable of pointer type">; def err_acc_clause_after_device_type : Error<"OpenACC clause '%0' may not follow a '%1' clause in a " "compute construct">; - +def err_acc_reduction_num_gangs_conflict + : Error< + "OpenACC 'reduction' clause may not appear on a 'parallel' construct " + "with a 'num_gangs' clause with more than 1 argument, have %0">; +def err_acc_reduction_type + : Error<"OpenACC 'reduction' variable must be of scalar type, sub-array, or a " + "composite of scalar types;%select{| sub-array base}1 type is %0">; +def err_acc_reduction_composite_type + : Error<"OpenACC 'reduction' variable must be a composite of scalar types; " + "%1 %select{is not a class or struct|is incomplete|is not an " + "aggregate}0">; +def err_acc_reduction_composite_member_type :Error< + "OpenACC 'reduction' composite variable must not have non-scalar field">; +def note_acc_reduction_composite_member_loc : Note<"invalid field is here">; + +// AMDGCN builtins diagnostics +def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">; +def note_amdgcn_global_load_lds_size_valid_value : Note<"size must be 1, 2, or 4">; } // end of sema component. diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index 8b4206e52cd48..e1f33d57a8980 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -299,6 +299,8 @@ class FileManager : public RefCountedBase { getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile, bool RequiresNullTerminator) const; + DirectoryEntry *&getRealDirEntry(const llvm::vfs::Status &Status); + public: /// Get the 'stat' information for the given \p Path. /// diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 09eb92d6f10d2..4061451b2150a 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -300,6 +300,7 @@ LANGOPT(HIPStdParInterposeAlloc, 1, 0, "Replace allocations / deallocations with LANGOPT(OpenACC , 1, 0, "OpenACC Enabled") +LANGOPT(MSVCEnableStdcMacro , 1, 0, "Define __STDC__ with '-fms-compatibility'") LANGOPT(SizedDeallocation , 1, 0, "sized deallocation") LANGOPT(AlignedAllocation , 1, 0, "aligned allocation") LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable") diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def index 7ecc51799468c..3e464abaafd92 100644 --- a/clang/include/clang/Basic/OpenACCClauses.def +++ b/clang/include/clang/Basic/OpenACCClauses.def @@ -46,6 +46,7 @@ VISIT_CLAUSE(NumGangs) VISIT_CLAUSE(NumWorkers) VISIT_CLAUSE(Present) VISIT_CLAUSE(Private) +VISIT_CLAUSE(Reduction) VISIT_CLAUSE(Self) VISIT_CLAUSE(VectorLength) VISIT_CLAUSE(Wait) diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h index 0e38a04e7164b..7b9d619a8aec6 100644 --- a/clang/include/clang/Basic/OpenACCKinds.h +++ b/clang/include/clang/Basic/OpenACCKinds.h @@ -514,6 +514,42 @@ enum class OpenACCReductionOperator { /// Invalid Reduction Clause Kind. Invalid, }; + +template +inline StreamTy &printOpenACCReductionOperator(StreamTy &Out, + OpenACCReductionOperator Op) { + switch (Op) { + case OpenACCReductionOperator::Addition: + return Out << "+"; + case OpenACCReductionOperator::Multiplication: + return Out << "*"; + case OpenACCReductionOperator::Max: + return Out << "max"; + case OpenACCReductionOperator::Min: + return Out << "min"; + case OpenACCReductionOperator::BitwiseAnd: + return Out << "&"; + case OpenACCReductionOperator::BitwiseOr: + return Out << "|"; + case OpenACCReductionOperator::BitwiseXOr: + return Out << "^"; + case OpenACCReductionOperator::And: + return Out << "&&"; + case OpenACCReductionOperator::Or: + return Out << "||"; + case OpenACCReductionOperator::Invalid: + return Out << ""; + } + llvm_unreachable("Unknown reduction operator kind"); +} +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out, + OpenACCReductionOperator Op) { + return printOpenACCReductionOperator(Out, Op); +} +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out, + OpenACCReductionOperator Op) { + return printOpenACCReductionOperator(Out, Op); +} } // namespace clang #endif // LLVM_CLANG_BASIC_OPENACCKINDS_H diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index a9ea71cd07774..03570f94de666 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -2186,9 +2186,6 @@ let TargetGuard = "sme2" in { def SVSQRSHRUN_X4 : SInst<"svqrshrun[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrshrun_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>; - def REINTERPRET_SVBOOL_TO_SVCOUNT : Inst<"svreinterpret[_c]", "}P", "Pc", MergeNone, "", [IsStreamingCompatible], []>; - def REINTERPRET_SVCOUNT_TO_SVBOOL : Inst<"svreinterpret[_b]", "P}", "Pc", MergeNone, "", [IsStreamingCompatible], []>; - // SQDMULH def SVSQDMULH_SINGLE_X2 : SInst<"svqdmulh[_single_{d}_x2]", "22d", "csil", MergeNone, "aarch64_sve_sqdmulh_single_vgx2", [IsStreaming], []>; def SVSQDMULH_SINGLE_X4 : SInst<"svqdmulh[_single_{d}_x4]", "44d", "csil", MergeNone, "aarch64_sve_sqdmulh_single_vgx4", [IsStreaming], []>; @@ -2197,6 +2194,9 @@ let TargetGuard = "sme2" in { } let TargetGuard = "sve2p1|sme2" in { + def REINTERPRET_SVBOOL_TO_SVCOUNT : Inst<"svreinterpret[_c]", "}P", "Pc", MergeNone, "", [IsStreamingCompatible], []>; + def REINTERPRET_SVCOUNT_TO_SVBOOL : Inst<"svreinterpret[_b]", "P}", "Pc", MergeNone, "", [IsStreamingCompatible], []>; + // SQRSHRN / UQRSHRN def SVQRSHRN_X2 : SInst<"svqrshrn[_n]_{0}[_{d}_x2]", "h2i", "i", MergeNone, "aarch64_sve_sqrshrn_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>; def SVUQRSHRN_X2 : SInst<"svqrshrn[_n]_{0}[_{d}_x2]", "e2i", "Ui", MergeNone, "aarch64_sve_uqrshrn_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 7bb781667e926..de2f245fb29f8 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -603,6 +603,7 @@ class MarshallingInfoVisibility // Key paths that are constant during parsing of options with the same key path prefix. defvar cplusplus = LangOpts<"CPlusPlus">; defvar cpp11 = LangOpts<"CPlusPlus11">; +defvar cpp14 = LangOpts<"CPlusPlus14">; defvar cpp17 = LangOpts<"CPlusPlus17">; defvar cpp20 = LangOpts<"CPlusPlus20">; defvar c99 = LangOpts<"C99">; @@ -2980,6 +2981,10 @@ def fms_compatibility : Flag<["-"], "fms-compatibility">, Group, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Enable full Microsoft Visual C++ compatibility">, MarshallingInfoFlag>; +def fms_define_stdc : Flag<["-"], "fms-define-stdc">, Group, + Visibility<[ClangOption, CC1Option, CLOption]>, + HelpText<"Define '__STDC__' to '1' in MSVC Compatibility mode">, + MarshallingInfoFlag>; def fms_extensions : Flag<["-"], "fms-extensions">, Group, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">, @@ -3388,10 +3393,9 @@ defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-arg NegFlag, BothFlags<[], [ClangOption], " C++17 relaxed template template argument matching">>; defm sized_deallocation : BoolFOption<"sized-deallocation", - LangOpts<"SizedDeallocation">, DefaultFalse, - PosFlag, - NegFlag>; + LangOpts<"SizedDeallocation">, Default, + PosFlag, + NegFlag, BothFlags<[], [ClangOption, CC1Option]>>; defm aligned_allocation : BoolFOption<"aligned-allocation", LangOpts<"AlignedAllocation">, Default, PosFlag, @@ -6111,14 +6115,10 @@ def mavx512cd : Flag<["-"], "mavx512cd">, Group; def mno_avx512cd : Flag<["-"], "mno-avx512cd">, Group; def mavx512dq : Flag<["-"], "mavx512dq">, Group; def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group; -def mavx512er : Flag<["-"], "mavx512er">, Group; -def mno_avx512er : Flag<["-"], "mno-avx512er">, Group; def mavx512fp16 : Flag<["-"], "mavx512fp16">, Group; def mno_avx512fp16 : Flag<["-"], "mno-avx512fp16">, Group; def mavx512ifma : Flag<["-"], "mavx512ifma">, Group; def mno_avx512ifma : Flag<["-"], "mno-avx512ifma">, Group; -def mavx512pf : Flag<["-"], "mavx512pf">, Group; -def mno_avx512pf : Flag<["-"], "mno-avx512pf">, Group; def mavx512vbmi : Flag<["-"], "mavx512vbmi">, Group; def mno_avx512vbmi : Flag<["-"], "mno-avx512vbmi">, Group; def mavx512vbmi2 : Flag<["-"], "mavx512vbmi2">, Group; @@ -6209,8 +6209,6 @@ def mpopcnt : Flag<["-"], "mpopcnt">, Group; def mno_popcnt : Flag<["-"], "mno-popcnt">, Group; def mprefetchi : Flag<["-"], "mprefetchi">, Group; def mno_prefetchi : Flag<["-"], "mno-prefetchi">, Group; -def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group; -def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group; def mprfchw : Flag<["-"], "mprfchw">, Group; def mno_prfchw : Flag<["-"], "mno-prfchw">, Group; def mptwrite : Flag<["-"], "mptwrite">, Group; @@ -8312,6 +8310,9 @@ def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, Alias; def _SLASH_X : CLFlag<"X">, HelpText<"Do not add %INCLUDE% to include search path">, Alias; +def _SLASH_Zc___STDC__ : CLFlag<"Zc:__STDC__">, + HelpText<"Define __STDC__">, + Alias; def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, HelpText<"Enable C++14 sized global deallocation functions">, Alias; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 5f04664141d29..8493026f5f7a6 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1646,8 +1646,12 @@ class Parser : public CodeCompletionHandler { void ParseLexedAttributes(ParsingClass &Class); void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, bool EnterScope, bool OnDefinition); + void ParseLexedCAttributeList(LateParsedAttrList &LA, bool EnterScope, + ParsedAttributes *OutAttrs = nullptr); void ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope, bool OnDefinition); + void ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope, + ParsedAttributes *OutAttrs = nullptr); void ParseLexedMethodDeclarations(ParsingClass &Class); void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM); void ParseLexedMethodDefs(ParsingClass &Class); @@ -2534,7 +2538,8 @@ class Parser : public CodeCompletionHandler { void ParseStructDeclaration( ParsingDeclSpec &DS, - llvm::function_ref FieldsCallback); + llvm::function_ref FieldsCallback, + LateParsedAttrList *LateFieldAttrs = nullptr); DeclGroupPtrTy ParseTopLevelStmtDecl(); @@ -2814,7 +2819,7 @@ class Parser : public CodeCompletionHandler { SourceLocation CorrectLocation); void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS, - Sema::TagUseKind TUK); + TagUseKind TUK); // FixItLoc = possible correct location for the attributes void ProhibitAttributes(ParsedAttributes &Attrs, @@ -2997,7 +3002,8 @@ class Parser : public CodeCompletionHandler { bool ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs, IdentifierInfo *AttrName, SourceLocation AttrNameLoc, - SourceLocation *EndLoc); + SourceLocation *EndLoc, + ParsedAttr::Form Form); IdentifierInfo *TryParseCXX11AttributeIdentifier( SourceLocation &Loc, @@ -3112,6 +3118,8 @@ class Parser : public CodeCompletionHandler { SourceLocation ScopeLoc, ParsedAttr::Form Form); + void DistributeCLateParsedAttrs(Decl *Dcl, LateParsedAttrList *LateAttrs); + void ParseBoundsAttribute(IdentifierInfo &AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, IdentifierInfo *ScopeName, SourceLocation ScopeLoc, @@ -3686,9 +3694,9 @@ class Parser : public CodeCompletionHandler { using OpenACCVarParseResult = std::pair; /// Parses a single variable in a variable list for OpenACC. - OpenACCVarParseResult ParseOpenACCVar(); + OpenACCVarParseResult ParseOpenACCVar(OpenACCClauseKind CK); /// Parses the variable list for the variety of places that take a var-list. - llvm::SmallVector ParseOpenACCVarList(); + llvm::SmallVector ParseOpenACCVarList(OpenACCClauseKind CK); /// Parses any parameters for an OpenACC Clause, including required/optional /// parens. OpenACCClauseParseResult diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5894239664c15..ec083f7cc09b7 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -174,7 +174,10 @@ class SemaHLSL; class SemaObjC; class SemaOpenACC; class SemaOpenMP; +class SemaPseudoObject; +class SemaRISCV; class SemaSYCL; +class SemaX86; class StandardConversionSequence; class Stmt; class StringLiteral; @@ -446,6 +449,13 @@ enum class CheckedConversionKind { ForBuiltinOverloadedOp }; +enum class TagUseKind { + Reference, // Reference to a tag: 'struct foo *X;' + Declaration, // Fwd decl of a tag: 'struct foo;' + Definition, // Definition of a tag: 'struct foo { int X; } Y;' + Friend // Friend declaration: 'friend struct foo;' +}; + /// Sema - This implements semantic analysis and AST building for C. /// \nosubgrouping class Sema final : public SemaBase { @@ -471,20 +481,18 @@ class Sema final : public SemaBase { // 18. Name Lookup (SemaLookup.cpp) // 19. Modules (SemaModule.cpp) // 20. C++ Overloading (SemaOverload.cpp) - // 21. Pseudo-Object (SemaPseudoObject.cpp) - // 22. Statements (SemaStmt.cpp) - // 23. `inline asm` Statement (SemaStmtAsm.cpp) - // 24. Statement Attribute Handling (SemaStmtAttr.cpp) - // 25. C++ Templates (SemaTemplate.cpp) - // 26. C++ Template Argument Deduction (SemaTemplateDeduction.cpp) - // 27. C++ Template Instantiation (SemaTemplateInstantiate.cpp) - // 28. C++ Template Declaration Instantiation + // 21. Statements (SemaStmt.cpp) + // 22. `inline asm` Statement (SemaStmtAsm.cpp) + // 23. Statement Attribute Handling (SemaStmtAttr.cpp) + // 24. C++ Templates (SemaTemplate.cpp) + // 25. C++ Template Argument Deduction (SemaTemplateDeduction.cpp) + // 26. C++ Template Instantiation (SemaTemplateInstantiate.cpp) + // 27. C++ Template Declaration Instantiation // (SemaTemplateInstantiateDecl.cpp) - // 29. C++ Variadic Templates (SemaTemplateVariadic.cpp) - // 30. Constraints and Concepts (SemaConcept.cpp) - // 31. Types (SemaType.cpp) - // 32. FixIt Helpers (SemaFixItUtils.cpp) - // 33. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) + // 28. C++ Variadic Templates (SemaTemplateVariadic.cpp) + // 29. Constraints and Concepts (SemaConcept.cpp) + // 30. Types (SemaType.cpp) + // 31. FixIt Helpers (SemaFixItUtils.cpp) /// \name Semantic Analysis /// Implementations are in Sema.cpp @@ -1015,11 +1023,26 @@ class Sema final : public SemaBase { return *OpenMPPtr; } + SemaPseudoObject &PseudoObject() { + assert(PseudoObjectPtr); + return *PseudoObjectPtr; + } + + SemaRISCV &RISCV() { + assert(RISCVPtr); + return *RISCVPtr; + } + SemaSYCL &SYCL() { assert(SYCLPtr); return *SYCLPtr; } + SemaX86 &X86() { + assert(X86Ptr); + return *X86Ptr; + } + /// Source of additional semantic information. IntrusiveRefCntPtr ExternalSource; @@ -1056,7 +1079,10 @@ class Sema final : public SemaBase { std::unique_ptr ObjCPtr; std::unique_ptr OpenACCPtr; std::unique_ptr OpenMPPtr; + std::unique_ptr PseudoObjectPtr; + std::unique_ptr RISCVPtr; std::unique_ptr SYCLPtr; + std::unique_ptr X86Ptr; ///@} @@ -2031,6 +2057,23 @@ class Sema final : public SemaBase { void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc); + bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result); + bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, + bool RangeIsError = true); + bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, + unsigned Multiple); + bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum); + bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, + unsigned ArgBits); + bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, + unsigned ArgBits); + + bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount); + bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount); + bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, + unsigned MaxArgCount); + bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount); + private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE = nullptr, @@ -2086,24 +2129,10 @@ class Sema final : public SemaBase { CallExpr *TheCall); bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, - ArrayRef ArgNums); - bool CheckX86BuiltinTileDuplicate(CallExpr *TheCall, ArrayRef ArgNums); - bool CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, - ArrayRef ArgNums); - bool CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); - bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall); - void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D, - const llvm::StringMap &FeatureMap); + bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, @@ -2133,16 +2162,6 @@ class Sema final : public SemaBase { ExprResult BuiltinNontemporalOverloaded(ExprResult TheCallResult); ExprResult AtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op); - bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result); - bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, - bool RangeIsError = true); - bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, - unsigned Multiple); - bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum); - bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, - unsigned ArgBits); - bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, - unsigned ArgBits); bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName); bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); @@ -3162,13 +3181,6 @@ class Sema final : public SemaBase { bool isDefinition, SourceLocation NewTagLoc, const IdentifierInfo *Name); - enum TagUseKind { - TUK_Reference, // Reference to a tag: 'struct foo *X;' - TUK_Declaration, // Fwd decl of a tag: 'struct foo;' - TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;' - TUK_Friend // Friend declaration: 'friend struct foo;' - }; - enum OffsetOfKind { // Not parsing a type within __builtin_offsetof. OOK_Outside, @@ -5100,6 +5112,13 @@ class Sema final : public SemaBase { Context == ExpressionEvaluationContext::UnevaluatedList; } + bool isPotentiallyEvaluated() const { + return Context == ExpressionEvaluationContext::PotentiallyEvaluated || + Context == + ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed || + Context == ExpressionEvaluationContext::ConstantEvaluated; + } + bool isConstantEvaluated() const { return Context == ExpressionEvaluationContext::ConstantEvaluated || Context == ExpressionEvaluationContext::ImmediateFunctionContext; @@ -5134,6 +5153,16 @@ class Sema final : public SemaBase { return ExprEvalContexts.back(); }; + ExpressionEvaluationContextRecord &parentEvaluationContext() { + assert(ExprEvalContexts.size() >= 2 && + "Must be in an expression evaluation context"); + return ExprEvalContexts[ExprEvalContexts.size() - 2]; + }; + + const ExpressionEvaluationContextRecord &parentEvaluationContext() const { + return const_cast(this)->parentEvaluationContext(); + }; + bool isBoundsAttrContext() const { return ExprEvalContexts.back().ExprContext == ExpressionEvaluationContextRecord::ExpressionKind:: @@ -5884,7 +5913,6 @@ class Sema final : public SemaBase { SourceLocation Loc, bool IsCompAssign); bool isValidSveBitcast(QualType srcType, QualType destType); - bool isValidRVVBitcast(QualType srcType, QualType destType); bool areMatrixTypesOfTheSameDimension(QualType srcTy, QualType destTy); @@ -6265,10 +6293,9 @@ class Sema final : public SemaBase { /// flag from previous context. void keepInLifetimeExtendingContext() { if (ExprEvalContexts.size() > 2 && - ExprEvalContexts[ExprEvalContexts.size() - 2] - .InLifetimeExtendingContext) { + parentEvaluationContext().InLifetimeExtendingContext) { auto &LastRecord = ExprEvalContexts.back(); - auto &PrevRecord = ExprEvalContexts[ExprEvalContexts.size() - 2]; + auto &PrevRecord = parentEvaluationContext(); LastRecord.InLifetimeExtendingContext = PrevRecord.InLifetimeExtendingContext; } @@ -6369,6 +6396,8 @@ class Sema final : public SemaBase { llvm::SmallVector, 1> ImplicitlyRetainedSelfLocs; + void maybeExtendBlockObject(ExprResult &E); + private: static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind); @@ -7055,7 +7084,9 @@ class Sema final : public SemaBase { StorageClass SC, ArrayRef Params, bool HasExplicitResultType); - void DiagnoseInvalidExplicitObjectParameterInLambda(CXXMethodDecl *Method); + /// Returns true if the explicit object parameter was invalid. + bool DiagnoseInvalidExplicitObjectParameterInLambda(CXXMethodDecl *Method, + SourceLocation CallLoc); /// Perform initialization analysis of the init-capture and perform /// any implicit conversions such as an lvalue-to-rvalue conversion if @@ -8367,29 +8398,6 @@ class Sema final : public SemaBase { // // - /// \name Pseudo-Object - /// Implementations are in SemaPseudoObject.cpp - ///@{ - -public: - void maybeExtendBlockObject(ExprResult &E); - - ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, - UnaryOperatorKind Opcode, Expr *Op); - ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, - BinaryOperatorKind Opcode, Expr *LHS, - Expr *RHS); - ExprResult checkPseudoObjectRValue(Expr *E); - Expr *recreateSyntacticForm(PseudoObjectExpr *E); - - ///@} - - // - // - // ------------------------------------------------------------------------- - // - // - /// \name Statements /// Implementations are in SemaStmt.cpp ///@{ @@ -10082,7 +10090,9 @@ class Sema final : public SemaBase { bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateArgumentLoc &Output); + TemplateArgumentLoc &Output, + SourceLocation Loc = {}, + const DeclarationName &Entity = {}); bool SubstTemplateArguments(ArrayRef Args, const MultiLevelTemplateArgumentList &TemplateArgs, @@ -11396,7 +11406,8 @@ class Sema final : public SemaBase { QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, SourceLocation AttrLoc); - QualType BuildCountAttributedArrayType(QualType WrappedTy, Expr *CountExpr); + QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy, + Expr *CountExpr); QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, SourceLocation AttrLoc); @@ -11699,27 +11710,6 @@ class Sema final : public SemaBase { /// Triggered by declaration-attribute processing. void ProcessAPINotes(Decl *D); - ///@} - // - // - // ------------------------------------------------------------------------- - // - // - - /// \name Name Lookup for RISC-V Vector Intrinsic - /// Implementations are in SemaRISCVVectorLookup.cpp - ///@{ - -public: - /// Indicate RISC-V vector builtin functions enabled or not. - bool DeclareRISCVVBuiltins = false; - - /// Indicate RISC-V SiFive vector builtin functions enabled or not. - bool DeclareRISCVSiFiveVectorBuiltins = false; - -private: - std::unique_ptr RVIntrinsicManager; - ///@} }; @@ -11742,9 +11732,6 @@ void Sema::PragmaStack::Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, AlignPackInfo Value); - -std::unique_ptr -CreateRISCVIntrinsicManager(Sema &S); } // end namespace clang #endif diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index f838fa97d33a2..6f69fa08939b8 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -66,9 +66,14 @@ class SemaOpenACC : public SemaBase { struct DeviceTypeDetails { SmallVector Archs; }; + struct ReductionDetails { + OpenACCReductionOperator Op; + SmallVector VarList; + }; std::variant + IntExprDetails, VarListDetails, WaitDetails, DeviceTypeDetails, + ReductionDetails> Details = std::monostate{}; public: @@ -170,6 +175,10 @@ class SemaOpenACC : public SemaBase { return const_cast(this)->getIntExprs(); } + OpenACCReductionOperator getReductionOp() const { + return std::get(Details).Op; + } + ArrayRef getVarList() { assert((ClauseKind == OpenACCClauseKind::Private || ClauseKind == OpenACCClauseKind::NoCreate || @@ -188,8 +197,13 @@ class SemaOpenACC : public SemaBase { ClauseKind == OpenACCClauseKind::PresentOrCreate || ClauseKind == OpenACCClauseKind::Attach || ClauseKind == OpenACCClauseKind::DevicePtr || + ClauseKind == OpenACCClauseKind::Reduction || ClauseKind == OpenACCClauseKind::FirstPrivate) && "Parsed clause kind does not have a var-list"); + + if (ClauseKind == OpenACCClauseKind::Reduction) + return std::get(Details).VarList; + return std::get(Details).VarList; } @@ -334,6 +348,13 @@ class SemaOpenACC : public SemaBase { Details = VarListDetails{std::move(VarList), IsReadOnly, IsZero}; } + void setReductionDetails(OpenACCReductionOperator Op, + llvm::SmallVector &&VarList) { + assert(ClauseKind == OpenACCClauseKind::Reduction && + "reduction details only valid on reduction"); + Details = ReductionDetails{Op, std::move(VarList)}; + } + void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector &&IntExprs) { assert(ClauseKind == OpenACCClauseKind::Wait && @@ -394,7 +415,11 @@ class SemaOpenACC : public SemaBase { /// Called when encountering a 'var' for OpenACC, ensures it is actually a /// declaration reference to a variable of the correct type. - ExprResult ActOnVar(Expr *VarExpr); + ExprResult ActOnVar(OpenACCClauseKind CK, Expr *VarExpr); + + /// Called while semantically analyzing the reduction clause, ensuring the var + /// is the correct kind of reference. + ExprResult CheckReductionVar(Expr *VarExpr); /// Called to check the 'var' type is a variable of pointer type, necessary /// for 'deviceptr' and 'attach' clauses. Returns true on success. diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 9927459bbc594..51981e1c9a8b9 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1390,9 +1390,7 @@ class SemaOpenMP : public SemaBase { bool checkTransformableLoopNest( OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, SmallVectorImpl &LoopHelpers, - Stmt *&Body, - SmallVectorImpl, 0>> - &OriginalInits); + Stmt *&Body, SmallVectorImpl> &OriginalInits); /// Helper to keep information about the current `omp begin/end declare /// variant` nesting. diff --git a/clang/include/clang/Sema/SemaPseudoObject.h b/clang/include/clang/Sema/SemaPseudoObject.h new file mode 100644 index 0000000000000..22d8be2b3726e --- /dev/null +++ b/clang/include/clang/Sema/SemaPseudoObject.h @@ -0,0 +1,40 @@ +//===----- SemaPseudoObject.h --- Semantic Analysis for Pseudo-Objects ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis for expressions involving +// pseudo-object references. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H +#define LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H + +#include "clang/AST/Expr.h" +#include "clang/AST/OperationKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Sema/Ownership.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { + +class SemaPseudoObject : public SemaBase { +public: + SemaPseudoObject(Sema &S); + + ExprResult checkIncDec(Scope *S, SourceLocation OpLoc, + UnaryOperatorKind Opcode, Expr *Op); + ExprResult checkAssignment(Scope *S, SourceLocation OpLoc, + BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS); + ExprResult checkRValue(Expr *E); + Expr *recreateSyntacticForm(PseudoObjectExpr *E); +}; + +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H \ No newline at end of file diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h new file mode 100644 index 0000000000000..b6dd81f8d4d80 --- /dev/null +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -0,0 +1,52 @@ +//===----- SemaRISCV.h ---- RISC-V target-specific routines ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to RISC-V. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMARISCV_H +#define LLVM_CLANG_SEMA_SEMARISCV_H + +#include "clang/AST/DeclBase.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/RISCVIntrinsicManager.h" +#include "clang/Sema/SemaBase.h" +#include "llvm/ADT/StringMap.h" +#include + +namespace clang { +class SemaRISCV : public SemaBase { +public: + SemaRISCV(Sema &S); + + bool CheckLMUL(CallExpr *TheCall, unsigned ArgNum); + bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D, + const llvm::StringMap &FeatureMap); + + bool isValidRVVBitcast(QualType srcType, QualType destType); + + /// Indicate RISC-V vector builtin functions enabled or not. + bool DeclareRVVBuiltins = false; + + /// Indicate RISC-V SiFive vector builtin functions enabled or not. + bool DeclareSiFiveVectorBuiltins = false; + + std::unique_ptr IntrinsicManager; +}; + +std::unique_ptr +CreateRISCVIntrinsicManager(Sema &S); +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMARISCV_H diff --git a/clang/include/clang/Sema/SemaX86.h b/clang/include/clang/Sema/SemaX86.h new file mode 100644 index 0000000000000..e322483294ec7 --- /dev/null +++ b/clang/include/clang/Sema/SemaX86.h @@ -0,0 +1,38 @@ +//===----- SemaX86.h ------- X86 target-specific routines -----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis functions specific to X86. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAX86_H +#define LLVM_CLANG_SEMA_SEMAX86_H + +#include "clang/AST/Expr.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/SemaBase.h" + +namespace clang { +class SemaX86 : public SemaBase { +public: + SemaX86(Sema &S); + + bool CheckBuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); + bool CheckBuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); + bool CheckBuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall); + bool CheckBuiltinTileArgumentsRange(CallExpr *TheCall, ArrayRef ArgNums); + bool CheckBuiltinTileDuplicate(CallExpr *TheCall, ArrayRef ArgNums); + bool CheckBuiltinTileRangeAndDuplicate(CallExpr *TheCall, + ArrayRef ArgNums); + bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); +}; +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAX86_H diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 1bb5fa27a2419..4ece4593f0738 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -601,11 +601,11 @@ class ASTReader /// An array of lexical contents of a declaration context, as a sequence of /// Decl::Kind, DeclID pairs. - using unalighed_decl_id_t = + using unaligned_decl_id_t = llvm::support::detail::packed_endian_specific_integral< serialization::DeclID, llvm::endianness::native, llvm::support::unaligned>; - using LexicalContents = ArrayRef; + using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. llvm::DenseMap> @@ -2246,7 +2246,7 @@ class ASTReader auto [Loc, ModuleFileIndex] = ReadUntranslatedSourceLocation(Raw, Seq); ModuleFile *OwningModuleFile = - ModuleFileIndex == 0 ? &MF : MF.DependentModules[ModuleFileIndex - 1]; + ModuleFileIndex == 0 ? &MF : MF.TransitiveImports[ModuleFileIndex - 1]; assert(!SourceMgr.isLoadedSourceLocation(Loc) && "Run out source location space"); diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 7d8cbe3d40f56..992d26a8b88c1 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -513,11 +513,11 @@ class ModuleFile { /// List of modules which this modules dependent on. Different /// from `Imports`, this includes indirectly imported modules too. - /// The order of DependentModules is significant. It should keep + /// The order of TransitiveImports is significant. It should keep /// the same order with that module file manager when we write /// the current module file. The value of the member will be initialized /// in `ASTReader::ReadModuleOffsetMap`. - llvm::SmallVector DependentModules; + llvm::SmallVector TransitiveImports; /// Determine whether this module was directly imported at /// any point during translation. diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 64414e3d37f75..40f443047bd4b 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1011,6 +1011,11 @@ def FloatLoopCounter : Checker<"FloatLoopCounter">, Dependencies<[SecuritySyntaxChecker]>, Documentation; +def SetgidSetuidOrderChecker : Checker<"SetgidSetuidOrder">, + HelpText<"Warn on possible reversed order of 'setgid(getgid()))' and " + "'setuid(getuid())' (CERT: POS36-C)">, + Documentation; + } // end "security" let ParentPackage = ENV in { @@ -1030,15 +1035,6 @@ let ParentPackage = ENV in { } // end "security.cert.env" -let ParentPackage = POSAlpha in { - - def PutenvWithAuto : Checker<"34c">, - HelpText<"Finds calls to the 'putenv' function which pass a pointer to " - "an automatic variable as the argument.">, - Documentation; - -} // end "alpha.cert.pos" - let ParentPackage = SecurityAlpha in { def ArrayBoundChecker : Checker<"ArrayBound">, @@ -1049,10 +1045,6 @@ def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">, HelpText<"Warn about buffer overflows (newer checker)">, Documentation; -def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, - HelpText<"Check for an out-of-bound pointer being returned to callers">, - Documentation; - def MallocOverflowSecurityChecker : Checker<"MallocOverflow">, HelpText<"Check for overflows in the arguments to malloc()">, Documentation; @@ -1073,6 +1065,15 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">, ]>, Documentation; +def PutenvStackArray : Checker<"PutenvStackArray">, + HelpText<"Finds calls to the function 'putenv' which pass a pointer to " + "an automatic (stack-allocated) array as the argument.">, + Documentation; + +def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, + HelpText<"Check for an out-of-bound pointer being returned to callers">, + Documentation; + } // end "alpha.security" //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 52eab5feb062b..a2398fef623ea 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -6494,7 +6494,8 @@ bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X, if (!TTPX->hasDefaultArgument() || !TTPY->hasDefaultArgument()) return false; - return hasSameType(TTPX->getDefaultArgument(), TTPY->getDefaultArgument()); + return hasSameType(TTPX->getDefaultArgument().getArgument().getAsType(), + TTPY->getDefaultArgument().getArgument().getAsType()); } if (auto *NTTPX = dyn_cast(X)) { @@ -6502,8 +6503,10 @@ bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X, if (!NTTPX->hasDefaultArgument() || !NTTPY->hasDefaultArgument()) return false; - Expr *DefaultArgumentX = NTTPX->getDefaultArgument()->IgnoreImpCasts(); - Expr *DefaultArgumentY = NTTPY->getDefaultArgument()->IgnoreImpCasts(); + Expr *DefaultArgumentX = + NTTPX->getDefaultArgument().getArgument().getAsExpr()->IgnoreImpCasts(); + Expr *DefaultArgumentY = + NTTPY->getDefaultArgument().getArgument().getAsExpr()->IgnoreImpCasts(); llvm::FoldingSetNodeID XID, YID; DefaultArgumentX->Profile(XID, *this, /*Canonical=*/true); DefaultArgumentY->Profile(YID, *this, /*Canonical=*/true); diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 7b0d5f9cc1a93..0680ff5e3a385 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1215,46 +1215,19 @@ class TemplateDiff { bool &NeedAddressOf) { if (!Iter.isEnd()) { switch (Iter->getKind()) { - default: - llvm_unreachable("unknown ArgumentKind"); - case TemplateArgument::Integral: - Value = Iter->getAsIntegral(); - HasInt = true; - IntType = Iter->getIntegralType(); - return; - case TemplateArgument::Declaration: { - VD = Iter->getAsDecl(); - QualType ArgType = Iter->getParamTypeForDecl(); - QualType VDType = VD->getType(); - if (ArgType->isPointerType() && - Context.hasSameType(ArgType->getPointeeType(), VDType)) - NeedAddressOf = true; - return; - } - case TemplateArgument::NullPtr: - IsNullPtr = true; - return; - case TemplateArgument::Expression: - E = Iter->getAsExpr(); - } - } else if (!Default->isParameterPack()) { - E = Default->getDefaultArgument(); - } - - if (!Iter.hasDesugaredTA()) return; - - const TemplateArgument& TA = Iter.getDesugaredTA(); - switch (TA.getKind()) { - default: - llvm_unreachable("unknown ArgumentKind"); + case TemplateArgument::StructuralValue: + // FIXME: Diffing of structural values is not implemented. + // There is no possible fallback in this case, this will show up + // as '(no argument)'. + return; case TemplateArgument::Integral: - Value = TA.getAsIntegral(); + Value = Iter->getAsIntegral(); HasInt = true; - IntType = TA.getIntegralType(); + IntType = Iter->getIntegralType(); return; case TemplateArgument::Declaration: { - VD = TA.getAsDecl(); - QualType ArgType = TA.getParamTypeForDecl(); + VD = Iter->getAsDecl(); + QualType ArgType = Iter->getParamTypeForDecl(); QualType VDType = VD->getType(); if (ArgType->isPointerType() && Context.hasSameType(ArgType->getPointeeType(), VDType)) @@ -1265,13 +1238,62 @@ class TemplateDiff { IsNullPtr = true; return; case TemplateArgument::Expression: - // TODO: Sometimes, the desugared template argument Expr differs from - // the sugared template argument Expr. It may be useful in the future - // but for now, it is just discarded. - if (!E) - E = TA.getAsExpr(); - return; + E = Iter->getAsExpr(); + break; + case TemplateArgument::Null: + case TemplateArgument::Type: + case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: + llvm_unreachable("TemplateArgument kind is not expected for NTTP"); + case TemplateArgument::Pack: + llvm_unreachable("TemplateArgument kind should be handled elsewhere"); + } + } else if (!Default->isParameterPack()) { + E = Default->getDefaultArgument().getArgument().getAsExpr(); } + + if (!Iter.hasDesugaredTA()) + return; + + const TemplateArgument &TA = Iter.getDesugaredTA(); + switch (TA.getKind()) { + case TemplateArgument::StructuralValue: + // FIXME: Diffing of structural values is not implemented. + // Just fall back to the expression. + return; + case TemplateArgument::Integral: + Value = TA.getAsIntegral(); + HasInt = true; + IntType = TA.getIntegralType(); + return; + case TemplateArgument::Declaration: { + VD = TA.getAsDecl(); + QualType ArgType = TA.getParamTypeForDecl(); + QualType VDType = VD->getType(); + if (ArgType->isPointerType() && + Context.hasSameType(ArgType->getPointeeType(), VDType)) + NeedAddressOf = true; + return; + } + case TemplateArgument::NullPtr: + IsNullPtr = true; + return; + case TemplateArgument::Expression: + // TODO: Sometimes, the desugared template argument Expr differs from + // the sugared template argument Expr. It may be useful in the future + // but for now, it is just discarded. + if (!E) + E = TA.getAsExpr(); + return; + case TemplateArgument::Null: + case TemplateArgument::Type: + case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: + llvm_unreachable("TemplateArgument kind is not expected for NTTP"); + case TemplateArgument::Pack: + llvm_unreachable("TemplateArgument kind should be handled elsewhere"); + } + llvm_unreachable("Unexpected TemplateArgument kind"); } /// DiffNonTypes - Handles any template parameters not handled by DiffTypes @@ -1914,6 +1936,11 @@ class TemplateDiff { return; } + if (E) { + PrintExpr(E); + return; + } + OS << "(no argument)"; } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 9ff8e1ea78d85..cab5ee6047956 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5917,11 +5917,11 @@ ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } if (D->hasDefaultArgument()) { - Expected ToDefaultArgOrErr = - import(D->getDefaultArgumentInfo()); + Expected ToDefaultArgOrErr = + import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); - ToD->setDefaultArgument(*ToDefaultArgOrErr); + ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); } return ToD; @@ -5949,10 +5949,11 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { return ToD; if (D->hasDefaultArgument()) { - ExpectedExpr ToDefaultArgOrErr = import(D->getDefaultArgument()); + Expected ToDefaultArgOrErr = + import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); - ToD->setDefaultArgument(*ToDefaultArgOrErr); + ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr); } return ToD; diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index c5868256b440d..0cf4e64f83b8d 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1883,7 +1883,8 @@ void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) { if (TTP->hasDefaultArgument()) { Out << " = "; - Out << TTP->getDefaultArgument().getAsString(Policy); + TTP->getDefaultArgument().getArgument().print(Policy, Out, + /*IncludeType=*/false); } } @@ -1897,7 +1898,7 @@ void DeclPrinter::VisitNonTypeTemplateParmDecl( if (NTTP->hasDefaultArgument()) { Out << " = "; - NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy, Indentation, - "\n", &Context); + NTTP->getDefaultArgument().getArgument().print(Policy, Out, + /*IncludeType=*/false); } } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 26765a5da1dc6..95ffd4784641f 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -669,23 +669,30 @@ TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, } SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { - return hasDefaultArgument() - ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc() - : SourceLocation(); + return hasDefaultArgument() ? getDefaultArgument().getLocation() + : SourceLocation(); } SourceRange TemplateTypeParmDecl::getSourceRange() const { if (hasDefaultArgument() && !defaultArgumentWasInherited()) return SourceRange(getBeginLoc(), - getDefaultArgumentInfo()->getTypeLoc().getEndLoc()); + getDefaultArgument().getSourceRange().getEnd()); // TypeDecl::getSourceRange returns a range containing name location, which is // wrong for unnamed template parameters. e.g: // it will return <[[typename>]] instead of <[[typename]]> - else if (getDeclName().isEmpty()) + if (getDeclName().isEmpty()) return SourceRange(getBeginLoc()); return TypeDecl::getSourceRange(); } +void TemplateTypeParmDecl::setDefaultArgument( + const ASTContext &C, const TemplateArgumentLoc &DefArg) { + if (DefArg.getArgument().isNull()) + DefaultArgument.set(nullptr); + else + DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); +} + unsigned TemplateTypeParmDecl::getDepth() const { return getTypeForDecl()->castAs()->getDepth(); } @@ -788,14 +795,21 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, SourceRange NonTypeTemplateParmDecl::getSourceRange() const { if (hasDefaultArgument() && !defaultArgumentWasInherited()) return SourceRange(getOuterLocStart(), - getDefaultArgument()->getSourceRange().getEnd()); + getDefaultArgument().getSourceRange().getEnd()); return DeclaratorDecl::getSourceRange(); } SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { - return hasDefaultArgument() - ? getDefaultArgument()->getSourceRange().getBegin() - : SourceLocation(); + return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin() + : SourceLocation(); +} + +void NonTypeTemplateParmDecl::setDefaultArgument( + const ASTContext &C, const TemplateArgumentLoc &DefArg) { + if (DefArg.getArgument().isNull()) + DefaultArgument.set(nullptr); + else + DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 70328c1f52af3..3eb7e7544df71 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1050,34 +1050,85 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, if (T->isRecordType()) { const Record *R = getRecord(E->getType()); - if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) { + if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) return this->visitInitializer(Inits[0]); + + auto initPrimitiveField = [=](const Record::Field *FieldToInit, + const Expr *Init, PrimType T) -> bool { + if (!this->visit(Init)) + return false; + + if (FieldToInit->isBitField()) { + if (!this->emitInitBitField(T, FieldToInit, E)) + return false; + } else { + if (!this->emitInitField(T, FieldToInit->Offset, E)) + return false; + } + return this->emitPopPtr(E); + }; + + auto initCompositeField = [=](const Record::Field *FieldToInit, + const Expr *Init) -> bool { + // Non-primitive case. Get a pointer to the field-to-initialize + // on the stack and recurse into visitInitializer(). + if (!this->emitGetPtrField(FieldToInit->Offset, Init)) + return false; + if (!this->visitInitializer(Init)) + return false; + return this->emitPopPtr(E); + }; + + if (R->isUnion()) { + if (Inits.size() == 0) { + // Zero-initialize the first union field. + if (R->getNumFields() == 0) + return this->emitFinishInit(E); + const Record::Field *FieldToInit = R->getField(0u); + QualType FieldType = FieldToInit->Desc->getType(); + if (std::optional T = classify(FieldType)) { + if (!this->visitZeroInitializer(*T, FieldType, E)) + return false; + if (!this->emitInitField(*T, FieldToInit->Offset, E)) + return false; + } + // FIXME: Non-primitive case? + } else { + const Expr *Init = Inits[0]; + const FieldDecl *FToInit = nullptr; + if (const auto *ILE = dyn_cast(E)) + FToInit = ILE->getInitializedFieldInUnion(); + else + FToInit = cast(E)->getInitializedFieldInUnion(); + + if (!this->emitDupPtr(E)) + return false; + + const Record::Field *FieldToInit = R->getField(FToInit); + if (std::optional T = classify(Init)) { + if (!initPrimitiveField(FieldToInit, Init, *T)) + return false; + } else { + if (!initCompositeField(FieldToInit, Init)) + return false; + } + } + return this->emitFinishInit(E); } + assert(!R->isUnion()); unsigned InitIndex = 0; for (const Expr *Init : Inits) { // Skip unnamed bitfields. while (InitIndex < R->getNumFields() && R->getField(InitIndex)->Decl->isUnnamedBitField()) ++InitIndex; - if (!this->emitDupPtr(E)) return false; if (std::optional T = classify(Init)) { const Record::Field *FieldToInit = R->getField(InitIndex); - if (!this->visit(Init)) - return false; - - if (FieldToInit->isBitField()) { - if (!this->emitInitBitField(*T, FieldToInit, E)) - return false; - } else { - if (!this->emitInitField(*T, FieldToInit->Offset, E)) - return false; - } - - if (!this->emitPopPtr(E)) + if (!initPrimitiveField(FieldToInit, Init, *T)) return false; ++InitIndex; } else { @@ -1095,21 +1146,13 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, // into the Record's fields. } else { const Record::Field *FieldToInit = R->getField(InitIndex); - // Non-primitive case. Get a pointer to the field-to-initialize - // on the stack and recurse into visitInitializer(). - if (!this->emitGetPtrField(FieldToInit->Offset, Init)) - return false; - - if (!this->visitInitializer(Init)) - return false; - - if (!this->emitPopPtr(E)) + if (!initCompositeField(FieldToInit, Init)) return false; ++InitIndex; } } } - return true; + return this->emitFinishInit(E); } if (T->isArrayType()) { @@ -1133,7 +1176,7 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, } } - return true; + return this->emitFinishInit(E); } if (const auto *ComplexTy = E->getType()->getAs()) { @@ -1594,6 +1637,36 @@ bool ByteCodeExprGen::VisitStringLiteral(const StringLiteral *E) { return true; } +template +bool ByteCodeExprGen::VisitObjCStringLiteral( + const ObjCStringLiteral *E) { + return this->delegate(E->getString()); +} + +template +bool ByteCodeExprGen::VisitSYCLUniqueStableNameExpr( + const SYCLUniqueStableNameExpr *E) { + if (DiscardResult) + return true; + + assert(!Initializing); + + auto &A = Ctx.getASTContext(); + std::string ResultStr = E->ComputeName(A); + + QualType CharTy = A.CharTy.withConst(); + APInt Size(A.getTypeSize(A.getSizeType()), ResultStr.size() + 1); + QualType ArrayTy = A.getConstantArrayType(CharTy, Size, nullptr, + ArraySizeModifier::Normal, 0); + + StringLiteral *SL = + StringLiteral::Create(A, ResultStr, StringLiteralKind::Ordinary, + /*Pascal=*/false, ArrayTy, E->getLocation()); + + unsigned StringIndex = P.createGlobalString(SL); + return this->emitGetPtrGlobal(StringIndex, E); +} + template bool ByteCodeExprGen::VisitCharacterLiteral( const CharacterLiteral *E) { @@ -2088,6 +2161,21 @@ bool ByteCodeExprGen::VisitCXXConstructExpr( if (T->isRecordType()) { const CXXConstructorDecl *Ctor = E->getConstructor(); + // If we're discarding a construct expression, we still need + // to allocate a variable and call the constructor and destructor. + if (DiscardResult) { + if (Ctor->isTrivial()) + return true; + assert(!Initializing); + std::optional LocalIndex = allocateLocal(E); + + if (!LocalIndex) + return false; + + if (!this->emitGetPtrLocal(*LocalIndex, E)) + return false; + } + // Zero initialization. if (E->requiresZeroInitialization()) { const Record *R = getRecord(E->getType()); @@ -2108,19 +2196,6 @@ bool ByteCodeExprGen::VisitCXXConstructExpr( assert(Func->hasThisPointer()); assert(!Func->hasRVO()); - // If we're discarding a construct expression, we still need - // to allocate a variable and call the constructor and destructor. - if (DiscardResult) { - assert(!Initializing); - std::optional LocalIndex = allocateLocal(E); - - if (!LocalIndex) - return false; - - if (!this->emitGetPtrLocal(*LocalIndex, E)) - return false; - } - // The This pointer is already on the stack because this is an initializer, // but we need to dup() so the call() below has its own copy. if (!this->emitDupPtr(E)) @@ -2538,8 +2613,6 @@ bool ByteCodeExprGen::VisitShuffleVectorExpr( assert(E->getNumSubExprs() > 2); const Expr *Vecs[] = {E->getExpr(0), E->getExpr(1)}; - assert(Vecs[0]->getType() == Vecs[1]->getType()); - const VectorType *VT = Vecs[0]->getType()->castAs(); PrimType ElemT = classifyPrim(VT->getElementType()); unsigned NumInputElems = VT->getNumElements(); @@ -2576,6 +2649,14 @@ bool ByteCodeExprGen::VisitShuffleVectorExpr( return true; } +template +bool ByteCodeExprGen::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) { + if (!E->isExpressibleAsConstantInitializer()) + return this->emitInvalid(E); + + return this->delegate(E->getSubExpr()); +} + template bool ByteCodeExprGen::discard(const Expr *E) { OptionScope Scope(this, /*NewDiscardResult=*/true, /*NewInitializing=*/false); @@ -2591,6 +2672,9 @@ bool ByteCodeExprGen::delegate(const Expr *E) { } template bool ByteCodeExprGen::visit(const Expr *E) { + if (E->getType().isNull()) + return false; + if (E->getType()->isVoidType()) return this->discard(E); @@ -3257,7 +3341,8 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { // write the result into. if (IsVirtual && !HasQualifier) { uint32_t VarArgSize = 0; - unsigned NumParams = Func->getNumWrittenParams(); + unsigned NumParams = + Func->getNumWrittenParams() + isa(E); for (unsigned I = NumParams, N = E->getNumArgs(); I != N; ++I) VarArgSize += align(primSize(classify(E->getArg(I)).value_or(PT_Ptr))); @@ -3371,6 +3456,9 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { switch (E->getOpcode()) { case UO_PostInc: { // x++ + if (!Ctx.getLangOpts().CPlusPlus14) + return this->emitInvalid(E); + if (!this->visit(SubExpr)) return false; @@ -3389,6 +3477,9 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E); } case UO_PostDec: { // x-- + if (!Ctx.getLangOpts().CPlusPlus14) + return this->emitInvalid(E); + if (!this->visit(SubExpr)) return false; @@ -3407,6 +3498,9 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E); } case UO_PreInc: { // ++x + if (!Ctx.getLangOpts().CPlusPlus14) + return this->emitInvalid(E); + if (!this->visit(SubExpr)) return false; @@ -3451,6 +3545,9 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return E->isGLValue() || this->emitLoadPop(*T, E); } case UO_PreDec: { // --x + if (!Ctx.getLangOpts().CPlusPlus14) + return this->emitInvalid(E); + if (!this->visit(SubExpr)) return false; @@ -3679,13 +3776,13 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { return this->emitGetPtrLocal(Offset, E); } else if (auto GlobalIndex = P.getGlobal(D)) { if (IsReference) - return this->emitGetGlobalPtr(*GlobalIndex, E); + return this->emitGetGlobal(classifyPrim(E), *GlobalIndex, E); return this->emitGetPtrGlobal(*GlobalIndex, E); } else if (const auto *PVD = dyn_cast(D)) { if (auto It = this->Params.find(PVD); It != this->Params.end()) { if (IsReference || !It->second.IsPtr) - return this->emitGetParamPtr(It->second.Offset, E); + return this->emitGetParam(classifyPrim(E), It->second.Offset, E); return this->emitGetPtrParam(It->second.Offset, E); } @@ -3716,7 +3813,8 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { } } else { if (const auto *VD = dyn_cast(D); - VD && VD->getAnyInitializer() && VD->getType().isConstQualified()) { + VD && VD->getAnyInitializer() && VD->getType().isConstQualified() && + !VD->isWeak()) { if (!this->visitVarDecl(VD)) return false; // Retry. @@ -3724,8 +3822,18 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { } } - if (std::optional I = P.getOrCreateDummy(D)) - return this->emitGetPtrGlobal(*I, E); + if (std::optional I = P.getOrCreateDummy(D)) { + if (!this->emitGetPtrGlobal(*I, E)) + return false; + if (E->getType()->isVoidType()) + return true; + // Convert the dummy pointer to another pointer type if we have to. + if (PrimType PT = classifyPrim(E); PT != PT_Ptr) { + if (!this->emitDecayPtr(PT_Ptr, PT, E)) + return false; + } + return true; + } return this->emitInvalidDeclRef(E, E); } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index e73a2f0334cf6..44c495240289f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -90,6 +90,8 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitOpaqueValueExpr(const OpaqueValueExpr *E); bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E); bool VisitStringLiteral(const StringLiteral *E); + bool VisitObjCStringLiteral(const ObjCStringLiteral *E); + bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E); bool VisitCharacterLiteral(const CharacterLiteral *E); bool VisitCompoundAssignOperator(const CompoundAssignOperator *E); bool VisitFloatCompoundAssignOperator(const CompoundAssignOperator *E); @@ -125,6 +127,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitAddrLabelExpr(const AddrLabelExpr *E); bool VisitConvertVectorExpr(const ConvertVectorExpr *E); bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E); + bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index d51a57e5e92ea..4ecfa0f9bfd75 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -164,7 +164,8 @@ std::optional Context::classify(QualType T) const { T->isFunctionType() || T->isSpecificBuiltinType(BuiltinType::BoundMember)) return PT_FnPtr; - if (T->isReferenceType() || T->isPointerType()) + if (T->isReferenceType() || T->isPointerType() || + T->isObjCObjectPointerType()) return PT_Ptr; if (const auto *AT = T->getAs()) diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp index d0466902247b4..746b765ca4216 100644 --- a/clang/lib/AST/Interp/Descriptor.cpp +++ b/clang/lib/AST/Interp/Descriptor.cpp @@ -137,9 +137,8 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst, } static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, - bool IsActive, const Descriptor *D, + bool IsActive, bool IsUnion, const Descriptor *D, unsigned FieldOffset) { - bool IsUnion = false; // FIXME auto *Desc = reinterpret_cast(Ptr + FieldOffset) - 1; Desc->Offset = FieldOffset; Desc->Desc = D; @@ -174,7 +173,7 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false); for (const auto &F : D->ElemRecord->fields()) - initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, F.Desc, + initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion, F.Desc, F.Offset); // If this is initializing a virtual base, we do NOT want to consider its @@ -193,7 +192,7 @@ static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, for (const auto &V : D->ElemRecord->bases()) initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false); for (const auto &F : D->ElemRecord->fields()) - initField(B, Ptr, IsConst, IsMutable, IsActive, F.Desc, F.Offset); + initField(B, Ptr, IsConst, IsMutable, IsActive, D->ElemRecord->isUnion(), F.Desc, F.Offset); for (const auto &V : D->ElemRecord->virtual_bases()) initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, true); } diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index e92d686c724cc..150a793da881d 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -101,6 +101,10 @@ static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc, Pointer FieldPtr = BasePtr.atField(F.Offset); QualType FieldType = F.Decl->getType(); + // Don't check inactive union members. + if (R->isUnion() && !FieldPtr.isActive()) + continue; + if (FieldType->isRecordType()) { Result &= CheckFieldsInitialized(S, Loc, FieldPtr, FieldPtr.getRecord()); } else if (FieldType->isIncompleteArrayType()) { diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 3e4da487e43c3..145fa65791da2 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -18,6 +18,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/CXXInheritance.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "llvm/ADT/APSInt.h" @@ -76,18 +77,15 @@ static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, } else { S.FFDiag(E); } - } else if (const auto *VD = dyn_cast(D)) { - if (!VD->getType().isConstQualified()) { - diagnoseNonConstVariable(S, OpPC, VD); - return false; - } - - // const, but no initializer. - if (!VD->getAnyInitializer()) { - diagnoseMissingInitializer(S, OpPC, VD); - return false; - } + return false; } + + if (!D->getType().isConstQualified()) + diagnoseNonConstVariable(S, OpPC, D); + else if (const auto *VD = dyn_cast(D); + VD && !VD->getAnyInitializer()) + diagnoseMissingInitializer(S, OpPC, VD); + return false; } @@ -104,6 +102,11 @@ static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, return; } + // Rather random, but this is to match the diagnostic output of the current + // interpreter. + if (isa(VD)) + return; + if (VD->getType()->isIntegralOrEnumerationType()) { S.FFDiag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD; S.Note(VD->getLocation(), diag::note_declared_at); @@ -454,16 +457,16 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckConstant(S, OpPC, Ptr)) return false; - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Read)) return false; if (!CheckExtern(S, OpPC, Ptr)) return false; if (!CheckRange(S, OpPC, Ptr, AK_Read)) return false; - if (!CheckInitialized(S, OpPC, Ptr, AK_Read)) - return false; if (!CheckActive(S, OpPC, Ptr, AK_Read)) return false; + if (!CheckInitialized(S, OpPC, Ptr, AK_Read)) + return false; if (!CheckTemporary(S, OpPC, Ptr, AK_Read)) return false; if (!CheckMutable(S, OpPC, Ptr)) @@ -474,7 +477,7 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckLive(S, OpPC, Ptr, AK_Assign)) return false; - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Assign)) return false; if (!CheckExtern(S, OpPC, Ptr)) return false; @@ -657,7 +660,8 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) { return diagnoseUnknownDecl(S, OpPC, D); } -bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { +bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK) { if (!Ptr.isDummy()) return true; @@ -666,7 +670,15 @@ bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!D) return false; - return diagnoseUnknownDecl(S, OpPC, D); + if (AK == AK_Read || AK == AK_Increment || AK == AK_Decrement) + return diagnoseUnknownDecl(S, OpPC, D); + + assert(AK == AK_Assign); + if (S.getLangOpts().CPlusPlus11) { + const SourceInfo &E = S.Current->getSource(OpPC); + S.FFDiag(E, diag::note_constexpr_modify_global); + } + return false; } bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F, diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index d9f23a4b8c965..eca1792e64718 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -56,7 +56,8 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK); /// Checks if a pointer is a dummy pointer. -bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr); +bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK); /// Checks if a pointer is null. bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr, @@ -588,7 +589,7 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { template ::T> bool Inc(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Increment)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) return false; @@ -602,7 +603,7 @@ bool Inc(InterpState &S, CodePtr OpPC) { template ::T> bool IncPop(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Increment)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Increment)) return false; @@ -617,7 +618,7 @@ bool IncPop(InterpState &S, CodePtr OpPC) { template ::T> bool Dec(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Decrement)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) return false; @@ -631,7 +632,7 @@ bool Dec(InterpState &S, CodePtr OpPC) { template ::T> bool DecPop(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); - if (!CheckDummy(S, OpPC, Ptr)) + if (!CheckDummy(S, OpPC, Ptr, AK_Decrement)) return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Decrement)) return false; @@ -1245,6 +1246,8 @@ inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) { return false; if (!CheckRange(S, OpPC, Ptr, CSK_Field)) return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; if (!CheckSubobject(S, OpPC, Ptr, CSK_Field)) return false; @@ -1333,16 +1336,19 @@ inline bool GetPtrThisBase(InterpState &S, CodePtr OpPC, uint32_t Off) { inline bool FinishInitPop(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); - if (Ptr.canBeInitialized()) + if (Ptr.canBeInitialized()) { Ptr.initialize(); + Ptr.activate(); + } return true; } inline bool FinishInit(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.peek(); - - if (Ptr.canBeInitialized()) + if (Ptr.canBeInitialized()) { Ptr.initialize(); + Ptr.activate(); + } return true; } @@ -1368,9 +1374,6 @@ inline bool GetPtrVirtBasePop(InterpState &S, CodePtr OpPC, const Pointer &Ptr = S.Stk.pop(); if (!CheckNull(S, OpPC, Ptr, CSK_Base)) return false; - if (Ptr.isDummy()) // FIXME: Once we have type info for dummy pointers, this - // needs to go. - return false; return VirtBaseHelper(S, OpPC, D, Ptr); } @@ -1536,9 +1539,6 @@ inline bool Memcpy(InterpState &S, CodePtr OpPC) { template bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, const Pointer &Ptr) { - if (!CheckRange(S, OpPC, Ptr, CSK_ArrayToPointer)) - return false; - // A zero offset does not change the pointer. if (Offset.isZero()) { S.Stk.push(Ptr); @@ -1556,8 +1556,12 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, if (!CheckArray(S, OpPC, Ptr)) return false; - uint64_t Index = Ptr.getIndex(); uint64_t MaxIndex = static_cast(Ptr.getNumElems()); + uint64_t Index; + if (Ptr.isOnePastEnd()) + Index = MaxIndex; + else + Index = Ptr.getIndex(); bool Invalid = false; // Helper to report an invalid offset, computed as APSInt. diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 565c85bc2e0c2..00206d09c113d 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -214,7 +214,7 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, if (!CheckLive(S, OpPC, StrPtr, AK_Read)) return false; - if (!CheckDummy(S, OpPC, StrPtr)) + if (!CheckDummy(S, OpPC, StrPtr, AK_Read)) return false; assert(StrPtr.getFieldDesc()->isPrimitiveArray()); diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index ee8cedccb8d4b..252f7ea46086f 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -144,13 +144,18 @@ APValue Pointer::toAPValue() const { // TODO: compute the offset into the object. CharUnits Offset = CharUnits::Zero(); - bool IsOnePastEnd = isOnePastEnd(); // Build the path into the object. Pointer Ptr = *this; while (Ptr.isField() || Ptr.isArrayElement()) { - if (Ptr.isArrayElement()) { - Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getIndex())); + if (Ptr.isArrayRoot()) { + Path.push_back(APValue::LValuePathEntry::ArrayIndex(0)); + Ptr = Ptr.getBase(); + } else if (Ptr.isArrayElement()) { + if (Ptr.isOnePastEnd()) + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getArray().getNumElems())); + else + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getIndex())); Ptr = Ptr.getArray(); } else { // TODO: figure out if base is virtual @@ -173,7 +178,7 @@ APValue Pointer::toAPValue() const { // Just invert the order of the elements. std::reverse(Path.begin(), Path.end()); - return APValue(Base, Offset, Path, IsOnePastEnd, /*IsNullPtr=*/false); + return APValue(Base, Offset, Path, /*IsOnePastEnd=*/false, /*IsNullPtr=*/false); } void Pointer::print(llvm::raw_ostream &OS) const { @@ -346,6 +351,7 @@ std::optional Pointer::toRValue(const Context &Ctx) const { } else { Ok &= Composite(FieldTy, FP, Value); } + ActiveField = FP.getFieldDesc()->asFieldDecl(); break; } } diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 9900f37e60d4e..93ca754d04a64 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -314,12 +314,14 @@ class Pointer { /// Returns the type of the innermost field. QualType getType() const { if (inPrimitiveArray() && Offset != asBlockPointer().Base) { - // Unfortunately, complex types are not array types in clang, but they are - // for us. + // Unfortunately, complex and vector types are not array types in clang, + // but they are for us. if (const auto *AT = getFieldDesc()->getType()->getAsArrayTypeUnsafe()) return AT->getElementType(); if (const auto *CT = getFieldDesc()->getType()->getAs()) return CT->getElementType(); + if (const auto *CT = getFieldDesc()->getType()->getAs()) + return CT->getElementType(); } return getFieldDesc()->getType(); } @@ -535,9 +537,6 @@ class Pointer { if (isZero()) return 0; - if (isElementPastEnd()) - return 1; - // narrow()ed element in a composite array. if (asBlockPointer().Base > sizeof(InlineDescriptor) && asBlockPointer().Base == Offset) @@ -556,12 +555,16 @@ class Pointer { if (!asBlockPointer().Pointee) return false; - return isElementPastEnd() || getSize() == getOffset(); + return isElementPastEnd() || + (getSize() == getOffset() && !isZeroSizeArray()); } /// Checks if the pointer is an out-of-bounds element pointer. bool isElementPastEnd() const { return Offset == PastEndMark; } + /// Checks if the pointer is pointing to a zero-size array. + bool isZeroSizeArray() const { return getFieldDesc()->isZeroSizeArray(); } + /// Dereferences the pointer, if it's live. template T &deref() const { assert(isLive() && "Invalid pointer"); diff --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h index 05a094d0c5b1f..604fb5dfde1e4 100644 --- a/clang/lib/AST/Interp/PrimType.h +++ b/clang/lib/AST/Interp/PrimType.h @@ -30,20 +30,20 @@ template class Integral; /// Enumeration of the primitive types of the VM. enum PrimType : unsigned { - PT_Sint8, - PT_Uint8, - PT_Sint16, - PT_Uint16, - PT_Sint32, - PT_Uint32, - PT_Sint64, - PT_Uint64, - PT_IntAP, - PT_IntAPS, - PT_Bool, - PT_Float, - PT_Ptr, - PT_FnPtr, + PT_Sint8 = 0, + PT_Uint8 = 1, + PT_Sint16 = 2, + PT_Uint16 = 3, + PT_Sint32 = 4, + PT_Uint32 = 5, + PT_Sint64 = 6, + PT_Uint64 = 7, + PT_IntAP = 8, + PT_IntAPS = 9, + PT_Bool = 10, + PT_Float = 11, + PT_Ptr = 12, + PT_FnPtr = 13, }; inline constexpr bool isPtrType(PrimType T) { diff --git a/clang/lib/AST/Interp/Record.cpp b/clang/lib/AST/Interp/Record.cpp index 6a0a28bc9124b..8ded765fc1c41 100644 --- a/clang/lib/AST/Interp/Record.cpp +++ b/clang/lib/AST/Interp/Record.cpp @@ -16,7 +16,7 @@ Record::Record(const RecordDecl *Decl, BaseList &&SrcBases, FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases, unsigned VirtualSize, unsigned BaseSize) : Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)), - BaseSize(BaseSize), VirtualSize(VirtualSize) { + BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()) { for (Base &V : SrcVirtualBases) VirtualBases.push_back({ V.Decl, V.Offset + BaseSize, V.Desc, V.R }); diff --git a/clang/lib/AST/Interp/Record.h b/clang/lib/AST/Interp/Record.h index cf0480b3f62fa..83e15b125f77a 100644 --- a/clang/lib/AST/Interp/Record.h +++ b/clang/lib/AST/Interp/Record.h @@ -53,7 +53,7 @@ class Record final { /// Returns the name of the underlying declaration. const std::string getName() const; /// Checks if the record is a union. - bool isUnion() const { return getDecl()->isUnion(); } + bool isUnion() const { return IsUnion; } /// Returns the size of the record. unsigned getSize() const { return BaseSize; } /// Returns the full size of the record, including records. @@ -132,6 +132,8 @@ class Record final { unsigned BaseSize; /// Size of all virtual bases. unsigned VirtualSize; + /// If this record is a union. + bool IsUnion; }; } // namespace interp diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 42608476b1c19..3bbb3a905e9b9 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -1028,7 +1028,7 @@ void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { if (D->hasDefaultArgument()) JOS.attributeObject("defaultArg", [=] { - Visit(D->getDefaultArgument(), SourceRange(), + Visit(D->getDefaultArgument().getArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), D->defaultArgumentWasInherited() ? "inherited from" : "previous"); }); @@ -1044,7 +1044,7 @@ void JSONNodeDumper::VisitNonTypeTemplateParmDecl( if (D->hasDefaultArgument()) JOS.attributeObject("defaultArg", [=] { - Visit(D->getDefaultArgument(), SourceRange(), + Visit(D->getDefaultArgument().getArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), D->defaultArgumentWasInherited() ? "inherited from" : "previous"); }); diff --git a/clang/lib/AST/ODRDiagsEmitter.cpp b/clang/lib/AST/ODRDiagsEmitter.cpp index 5b1cdc16e2ea2..37f0f68c92355 100644 --- a/clang/lib/AST/ODRDiagsEmitter.cpp +++ b/clang/lib/AST/ODRDiagsEmitter.cpp @@ -1409,13 +1409,15 @@ bool ODRDiagsEmitter::diagnoseMismatch( } if (HasFirstDefaultArgument && HasSecondDefaultArgument) { - QualType FirstType = FirstTTPD->getDefaultArgument(); - QualType SecondType = SecondTTPD->getDefaultArgument(); - if (computeODRHash(FirstType) != computeODRHash(SecondType)) { + TemplateArgument FirstTA = + FirstTTPD->getDefaultArgument().getArgument(); + TemplateArgument SecondTA = + SecondTTPD->getDefaultArgument().getArgument(); + if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) { DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument) - << (i + 1) << FirstType; + << (i + 1) << FirstTA; DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument) - << (i + 1) << SecondType; + << (i + 1) << SecondTA; return true; } } @@ -1521,8 +1523,11 @@ bool ODRDiagsEmitter::diagnoseMismatch( } if (HasFirstDefaultArgument && HasSecondDefaultArgument) { - Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument(); - Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument(); + TemplateArgument FirstDefaultArgument = + FirstNTTPD->getDefaultArgument().getArgument(); + TemplateArgument SecondDefaultArgument = + SecondNTTPD->getDefaultArgument().getArgument(); + if (computeODRHash(FirstDefaultArgument) != computeODRHash(SecondDefaultArgument)) { DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument) diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 6f04739cf6693..246e56231539a 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -462,7 +462,7 @@ class ODRDeclVisitor : public ConstDeclVisitor { D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); Hash.AddBoolean(hasDefaultArgument); if (hasDefaultArgument) { - AddTemplateArgument(D->getDefaultArgument()); + AddTemplateArgument(D->getDefaultArgument().getArgument()); } Hash.AddBoolean(D->isParameterPack()); @@ -480,7 +480,7 @@ class ODRDeclVisitor : public ConstDeclVisitor { D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); Hash.AddBoolean(hasDefaultArgument); if (hasDefaultArgument) { - AddStmt(D->getDefaultArgument()); + AddTemplateArgument(D->getDefaultArgument().getArgument()); } Hash.AddBoolean(D->isParameterPack()); diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp index 8ff6dabcbc48e..cb2c7f98be75c 100644 --- a/clang/lib/AST/OpenACCClause.cpp +++ b/clang/lib/AST/OpenACCClause.cpp @@ -35,7 +35,7 @@ bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) { OpenACCAttachClause::classof(C) || OpenACCNoCreateClause::classof(C) || OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) || OpenACCCopyInClause::classof(C) || OpenACCCopyOutClause::classof(C) || - OpenACCCreateClause::classof(C); + OpenACCReductionClause::classof(C) || OpenACCCreateClause::classof(C); } bool OpenACCClauseWithCondition::classof(const OpenACCClause *C) { return OpenACCIfClause::classof(C) || OpenACCSelfClause::classof(C); @@ -310,6 +310,16 @@ OpenACCDeviceTypeClause *OpenACCDeviceTypeClause::Create( OpenACCDeviceTypeClause(K, BeginLoc, LParenLoc, Archs, EndLoc); } +OpenACCReductionClause *OpenACCReductionClause::Create( + const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + OpenACCReductionOperator Operator, ArrayRef VarList, + SourceLocation EndLoc) { + void *Mem = C.Allocate( + OpenACCReductionClause::totalSizeToAlloc(VarList.size())); + return new (Mem) + OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc); +} + //===----------------------------------------------------------------------===// // OpenACC clauses printing methods //===----------------------------------------------------------------------===// @@ -445,6 +455,14 @@ void OpenACCClausePrinter::VisitCreateClause(const OpenACCCreateClause &C) { OS << ")"; } +void OpenACCClausePrinter::VisitReductionClause( + const OpenACCReductionClause &C) { + OS << "reduction(" << C.getReductionOp() << ": "; + llvm::interleaveComma(C.getVarList(), OS, + [&](const Expr *E) { printExpr(E); }); + OS << ")"; +} + void OpenACCClausePrinter::VisitWaitClause(const OpenACCWaitClause &C) { OS << "wait"; if (!C.getLParenLoc().isInvalid()) { diff --git a/clang/lib/AST/ParentMap.cpp b/clang/lib/AST/ParentMap.cpp index 3d6a1cc84c7b1..534793b837bbb 100644 --- a/clang/lib/AST/ParentMap.cpp +++ b/clang/lib/AST/ParentMap.cpp @@ -97,6 +97,22 @@ static void BuildParentMap(MapTy& M, Stmt* S, BuildParentMap(M, SubStmt, OVMode); } break; + case Stmt::CXXDefaultArgExprClass: + if (auto *Arg = dyn_cast(S)) { + if (Arg->hasRewrittenInit()) { + M[Arg->getExpr()] = S; + BuildParentMap(M, Arg->getExpr(), OVMode); + } + } + break; + case Stmt::CXXDefaultInitExprClass: + if (auto *Init = dyn_cast(S)) { + if (Init->hasRewrittenInit()) { + M[Init->getExpr()] = S; + BuildParentMap(M, Init->getExpr(), OVMode); + } + } + break; default: for (Stmt *SubStmt : S->children()) { if (SubStmt) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index caab4ab0ef160..00b8c43af035c 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2588,6 +2588,12 @@ void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) { /// Nothing to do here, there are no sub-statements. void OpenACCClauseProfiler::VisitDeviceTypeClause( const OpenACCDeviceTypeClause &Clause) {} + +void OpenACCClauseProfiler::VisitReductionClause( + const OpenACCReductionClause &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); +} } // namespace void StmtProfiler::VisitOpenACCComputeConstruct( diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 3310d7dc24c59..a7ee973b7f7d0 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -538,9 +538,19 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, Out << "nullptr"; break; - case Template: - getAsTemplate().print(Out, Policy, TemplateName::Qualified::Fully); + case Template: { + TemplateName TN = getAsTemplate(); + if (const auto *TD = TN.getAsTemplateDecl(); + TD && TD->getDeclName().isEmpty()) { + assert(isa(TD) && + "Unexpected anonymous template"); + const auto *TTP = cast(TD); + Out << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex(); + } else { + TN.print(Out, Policy, TemplateName::Qualified::Fully); + } break; + } case TemplateExpansion: getAsTemplateOrTemplatePattern().print(Out, Policy); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index efcd74717a4e2..4a1e94ffe283b 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -457,6 +457,10 @@ void TextNodeDumper::Visit(const OpenACCClause *C) { }); OS << ")"; break; + case OpenACCClauseKind::Reduction: + OS << " clause Operator: " + << cast(C)->getReductionOp(); + break; default: // Nothing to do here. break; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 3b90b8229dd18..04f105c128872 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -632,6 +632,16 @@ bool Type::isStructureType() const { return false; } +bool Type::isStructureTypeWithFlexibleArrayMember() const { + const auto *RT = getAs(); + if (!RT) + return false; + const auto *Decl = RT->getDecl(); + if (!Decl->isStruct()) + return false; + return Decl->hasFlexibleArrayMember(); +} + bool Type::isObjCBoxableRecordType() const { if (const auto *RT = getAs()) return RT->getDecl()->hasAttr(); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 87f0a8728d850..5ed56b367a46a 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2273,16 +2273,17 @@ bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, if (auto *TTPD = dyn_cast(Param)) { return TTPD->hasDefaultArgument() && - isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(), - Args, Depth); + isSubstitutedTemplateArgument( + Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth); } else if (auto *TTPD = dyn_cast(Param)) { return TTPD->hasDefaultArgument() && isSubstitutedTemplateArgument( Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth); } else if (auto *NTTPD = dyn_cast(Param)) { return NTTPD->hasDefaultArgument() && - isSubstitutedTemplateArgument(Ctx, Arg, NTTPD->getDefaultArgument(), - Args, Depth); + isSubstitutedTemplateArgument( + Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args, + Depth); } return false; } diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 64e6155de090c..02317257c2740 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -556,6 +556,10 @@ class CFGBuilder { private: // Visitors to walk an AST and construct the CFG. + CFGBlock *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Default, + AddStmtChoice asc); + CFGBlock *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Default, + AddStmtChoice asc); CFGBlock *VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc); CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc); CFGBlock *VisitAttributedStmt(AttributedStmt *A, AddStmtChoice asc); @@ -2254,16 +2258,10 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc, asc, ExternallyDestructed); case Stmt::CXXDefaultArgExprClass: + return VisitCXXDefaultArgExpr(cast(S), asc); + case Stmt::CXXDefaultInitExprClass: - // FIXME: The expression inside a CXXDefaultArgExpr is owned by the - // called function's declaration, not by the caller. If we simply add - // this expression to the CFG, we could end up with the same Expr - // appearing multiple times (PR13385). - // - // It's likewise possible for multiple CXXDefaultInitExprs for the same - // expression to be used in the same function (through aggregate - // initialization). - return VisitStmt(S, asc); + return VisitCXXDefaultInitExpr(cast(S), asc); case Stmt::CXXBindTemporaryExprClass: return VisitCXXBindTemporaryExpr(cast(S), asc); @@ -2433,6 +2431,40 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt *S) { return B; } +CFGBlock *CFGBuilder::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Arg, + AddStmtChoice asc) { + if (Arg->hasRewrittenInit()) { + if (asc.alwaysAdd(*this, Arg)) { + autoCreateBlock(); + appendStmt(Block, Arg); + } + return VisitStmt(Arg->getExpr(), asc); + } + + // We can't add the default argument if it's not rewritten because the + // expression inside a CXXDefaultArgExpr is owned by the called function's + // declaration, not by the caller, we could end up with the same expression + // appearing multiple times. + return VisitStmt(Arg, asc); +} + +CFGBlock *CFGBuilder::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Init, + AddStmtChoice asc) { + if (Init->hasRewrittenInit()) { + if (asc.alwaysAdd(*this, Init)) { + autoCreateBlock(); + appendStmt(Block, Init); + } + return VisitStmt(Init->getExpr(), asc); + } + + // We can't add the default initializer if it's not rewritten because multiple + // CXXDefaultInitExprs for the same sub-expression to be used in the same + // function (through aggregate initialization). we could end up with the same + // expression appearing multiple times. + return VisitStmt(Init, asc); +} + CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) { if (asc.alwaysAdd(*this, ILE)) { autoCreateBlock(); diff --git a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt index 6631fe27f3d90..05cdaa7e27823 100644 --- a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt +++ b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt @@ -2,6 +2,7 @@ add_clang_library(clangAnalysisFlowSensitive AdornedCFG.cpp Arena.cpp ASTOps.cpp + CNFFormula.cpp DataflowAnalysisContext.cpp DataflowEnvironment.cpp Formula.cpp @@ -36,3 +37,4 @@ add_custom_command(OUTPUT HTMLLogger.inc DEPENDS ${CLANG_SOURCE_DIR}/utils/bundle_resources.py HTMLLogger.html HTMLLogger.css HTMLLogger.js VERBATIM) add_custom_target(clangAnalysisFlowSensitiveResources DEPENDS HTMLLogger.inc) +set_target_properties(clangAnalysisFlowSensitiveResources PROPERTIES FOLDER "Clang/Misc") diff --git a/clang/lib/Analysis/FlowSensitive/CNFFormula.cpp b/clang/lib/Analysis/FlowSensitive/CNFFormula.cpp new file mode 100644 index 0000000000000..2410ce1e7bd60 --- /dev/null +++ b/clang/lib/Analysis/FlowSensitive/CNFFormula.cpp @@ -0,0 +1,303 @@ +//===- CNFFormula.cpp -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A representation of a boolean formula in 3-CNF. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/FlowSensitive/CNFFormula.h" +#include "llvm/ADT/DenseSet.h" + +#include + +namespace clang { +namespace dataflow { + +namespace { + +/// Applies simplifications while building up a BooleanFormula. +/// We keep track of unit clauses, which tell us variables that must be +/// true/false in any model that satisfies the overall formula. +/// Such variables can be dropped from subsequently-added clauses, which +/// may in turn yield more unit clauses or even a contradiction. +/// The total added complexity of this preprocessing is O(N) where we +/// for every clause, we do a lookup for each unit clauses. +/// The lookup is O(1) on average. This method won't catch all +/// contradictory formulas, more passes can in principle catch +/// more cases but we leave all these and the general case to the +/// proper SAT solver. +struct CNFFormulaBuilder { + // Formula should outlive CNFFormulaBuilder. + explicit CNFFormulaBuilder(CNFFormula &CNF) : Formula(CNF) {} + + /// Adds the `L1 v ... v Ln` clause to the formula. Applies + /// simplifications, based on single-literal clauses. + /// + /// Requirements: + /// + /// `Li` must not be `NullLit`. + /// + /// All literals must be distinct. + void addClause(ArrayRef Literals) { + // We generate clauses with up to 3 literals in this file. + assert(!Literals.empty() && Literals.size() <= 3); + // Contains literals of the simplified clause. + llvm::SmallVector Simplified; + for (auto L : Literals) { + assert(L != NullLit && + llvm::all_of(Simplified, [L](Literal S) { return S != L; })); + auto X = var(L); + if (trueVars.contains(X)) { // X must be true + if (isPosLit(L)) + return; // Omit clause `(... v X v ...)`, it is `true`. + else + continue; // Omit `!X` from `(... v !X v ...)`. + } + if (falseVars.contains(X)) { // X must be false + if (isNegLit(L)) + return; // Omit clause `(... v !X v ...)`, it is `true`. + else + continue; // Omit `X` from `(... v X v ...)`. + } + Simplified.push_back(L); + } + if (Simplified.empty()) { + // Simplification made the clause empty, which is equivalent to `false`. + // We already know that this formula is unsatisfiable. + Formula.addClause(Simplified); + return; + } + if (Simplified.size() == 1) { + // We have new unit clause. + const Literal lit = Simplified.front(); + const Variable v = var(lit); + if (isPosLit(lit)) + trueVars.insert(v); + else + falseVars.insert(v); + } + Formula.addClause(Simplified); + } + + /// Returns true if we observed a contradiction while adding clauses. + /// In this case then the formula is already known to be unsatisfiable. + bool isKnownContradictory() { return Formula.knownContradictory(); } + +private: + CNFFormula &Formula; + llvm::DenseSet trueVars; + llvm::DenseSet falseVars; +}; + +} // namespace + +CNFFormula::CNFFormula(Variable LargestVar) + : LargestVar(LargestVar), KnownContradictory(false) { + Clauses.push_back(0); + ClauseStarts.push_back(0); +} + +void CNFFormula::addClause(ArrayRef lits) { + assert(llvm::all_of(lits, [](Literal L) { return L != NullLit; })); + + if (lits.empty()) + KnownContradictory = true; + + const size_t S = Clauses.size(); + ClauseStarts.push_back(S); + Clauses.insert(Clauses.end(), lits.begin(), lits.end()); +} + +CNFFormula buildCNF(const llvm::ArrayRef &Formulas, + llvm::DenseMap &Atomics) { + // The general strategy of the algorithm implemented below is to map each + // of the sub-values in `Vals` to a unique variable and use these variables in + // the resulting CNF expression to avoid exponential blow up. The number of + // literals in the resulting formula is guaranteed to be linear in the number + // of sub-formulas in `Vals`. + + // Map each sub-formula in `Vals` to a unique variable. + llvm::DenseMap FormulaToVar; + // Store variable identifiers and Atom of atomic booleans. + Variable NextVar = 1; + { + std::queue UnprocessedFormulas; + for (const Formula *F : Formulas) + UnprocessedFormulas.push(F); + while (!UnprocessedFormulas.empty()) { + Variable Var = NextVar; + const Formula *F = UnprocessedFormulas.front(); + UnprocessedFormulas.pop(); + + if (!FormulaToVar.try_emplace(F, Var).second) + continue; + ++NextVar; + + for (const Formula *Op : F->operands()) + UnprocessedFormulas.push(Op); + if (F->kind() == Formula::AtomRef) + Atomics[Var] = F->getAtom(); + } + } + + auto GetVar = [&FormulaToVar](const Formula *F) { + auto ValIt = FormulaToVar.find(F); + assert(ValIt != FormulaToVar.end()); + return ValIt->second; + }; + + CNFFormula CNF(NextVar - 1); + std::vector ProcessedSubVals(NextVar, false); + CNFFormulaBuilder builder(CNF); + + // Add a conjunct for each variable that represents a top-level conjunction + // value in `Vals`. + for (const Formula *F : Formulas) + builder.addClause(posLit(GetVar(F))); + + // Add conjuncts that represent the mapping between newly-created variables + // and their corresponding sub-formulas. + std::queue UnprocessedFormulas; + for (const Formula *F : Formulas) + UnprocessedFormulas.push(F); + while (!UnprocessedFormulas.empty()) { + const Formula *F = UnprocessedFormulas.front(); + UnprocessedFormulas.pop(); + const Variable Var = GetVar(F); + + if (ProcessedSubVals[Var]) + continue; + ProcessedSubVals[Var] = true; + + switch (F->kind()) { + case Formula::AtomRef: + break; + case Formula::Literal: + CNF.addClause(F->literal() ? posLit(Var) : negLit(Var)); + break; + case Formula::And: { + const Variable LHS = GetVar(F->operands()[0]); + const Variable RHS = GetVar(F->operands()[1]); + + if (LHS == RHS) { + // `X <=> (A ^ A)` is equivalent to `(!X v A) ^ (X v !A)` which is + // already in conjunctive normal form. Below we add each of the + // conjuncts of the latter expression to the result. + builder.addClause({negLit(Var), posLit(LHS)}); + builder.addClause({posLit(Var), negLit(LHS)}); + } else { + // `X <=> (A ^ B)` is equivalent to `(!X v A) ^ (!X v B) ^ (X v !A v + // !B)` which is already in conjunctive normal form. Below we add each + // of the conjuncts of the latter expression to the result. + builder.addClause({negLit(Var), posLit(LHS)}); + builder.addClause({negLit(Var), posLit(RHS)}); + builder.addClause({posLit(Var), negLit(LHS), negLit(RHS)}); + } + break; + } + case Formula::Or: { + const Variable LHS = GetVar(F->operands()[0]); + const Variable RHS = GetVar(F->operands()[1]); + + if (LHS == RHS) { + // `X <=> (A v A)` is equivalent to `(!X v A) ^ (X v !A)` which is + // already in conjunctive normal form. Below we add each of the + // conjuncts of the latter expression to the result. + builder.addClause({negLit(Var), posLit(LHS)}); + builder.addClause({posLit(Var), negLit(LHS)}); + } else { + // `X <=> (A v B)` is equivalent to `(!X v A v B) ^ (X v !A) ^ (X v + // !B)` which is already in conjunctive normal form. Below we add each + // of the conjuncts of the latter expression to the result. + builder.addClause({negLit(Var), posLit(LHS), posLit(RHS)}); + builder.addClause({posLit(Var), negLit(LHS)}); + builder.addClause({posLit(Var), negLit(RHS)}); + } + break; + } + case Formula::Not: { + const Variable Operand = GetVar(F->operands()[0]); + + // `X <=> !Y` is equivalent to `(!X v !Y) ^ (X v Y)` which is + // already in conjunctive normal form. Below we add each of the + // conjuncts of the latter expression to the result. + builder.addClause({negLit(Var), negLit(Operand)}); + builder.addClause({posLit(Var), posLit(Operand)}); + break; + } + case Formula::Implies: { + const Variable LHS = GetVar(F->operands()[0]); + const Variable RHS = GetVar(F->operands()[1]); + + // `X <=> (A => B)` is equivalent to + // `(X v A) ^ (X v !B) ^ (!X v !A v B)` which is already in + // conjunctive normal form. Below we add each of the conjuncts of + // the latter expression to the result. + builder.addClause({posLit(Var), posLit(LHS)}); + builder.addClause({posLit(Var), negLit(RHS)}); + builder.addClause({negLit(Var), negLit(LHS), posLit(RHS)}); + break; + } + case Formula::Equal: { + const Variable LHS = GetVar(F->operands()[0]); + const Variable RHS = GetVar(F->operands()[1]); + + if (LHS == RHS) { + // `X <=> (A <=> A)` is equivalent to `X` which is already in + // conjunctive normal form. Below we add each of the conjuncts of the + // latter expression to the result. + builder.addClause(posLit(Var)); + + // No need to visit the sub-values of `Val`. + continue; + } + // `X <=> (A <=> B)` is equivalent to + // `(X v A v B) ^ (X v !A v !B) ^ (!X v A v !B) ^ (!X v !A v B)` which + // is already in conjunctive normal form. Below we add each of the + // conjuncts of the latter expression to the result. + builder.addClause({posLit(Var), posLit(LHS), posLit(RHS)}); + builder.addClause({posLit(Var), negLit(LHS), negLit(RHS)}); + builder.addClause({negLit(Var), posLit(LHS), negLit(RHS)}); + builder.addClause({negLit(Var), negLit(LHS), posLit(RHS)}); + break; + } + } + if (builder.isKnownContradictory()) { + return CNF; + } + for (const Formula *Child : F->operands()) + UnprocessedFormulas.push(Child); + } + + // Unit clauses that were added later were not + // considered for the simplification of earlier clauses. Do a final + // pass to find more opportunities for simplification. + CNFFormula FinalCNF(NextVar - 1); + CNFFormulaBuilder FinalBuilder(FinalCNF); + + // Collect unit clauses. + for (ClauseID C = 1; C <= CNF.numClauses(); ++C) { + if (CNF.clauseSize(C) == 1) { + FinalBuilder.addClause(CNF.clauseLiterals(C)[0]); + } + } + + // Add all clauses that were added previously, preserving the order. + for (ClauseID C = 1; C <= CNF.numClauses(); ++C) { + FinalBuilder.addClause(CNF.clauseLiterals(C)); + if (FinalBuilder.isKnownContradictory()) { + break; + } + } + // It is possible there were new unit clauses again, but + // we stop here and leave the rest to the solver algorithm. + return FinalCNF; +} + +} // namespace dataflow +} // namespace clang diff --git a/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp b/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp index 3ef3637535324..a39f0e0b29ad1 100644 --- a/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp +++ b/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp @@ -12,105 +12,31 @@ //===----------------------------------------------------------------------===// #include -#include -#include -#include #include +#include "clang/Analysis/FlowSensitive/CNFFormula.h" #include "clang/Analysis/FlowSensitive/Formula.h" #include "clang/Analysis/FlowSensitive/Solver.h" #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" namespace clang { namespace dataflow { -// `WatchedLiteralsSolver` is an implementation of Algorithm D from Knuth's -// The Art of Computer Programming Volume 4: Satisfiability, Fascicle 6. It is -// based on the backtracking DPLL algorithm [1], keeps references to a single -// "watched" literal per clause, and uses a set of "active" variables to perform -// unit propagation. -// -// The solver expects that its input is a boolean formula in conjunctive normal -// form that consists of clauses of at least one literal. A literal is either a -// boolean variable or its negation. Below we define types, data structures, and -// utilities that are used to represent boolean formulas in conjunctive normal -// form. -// -// [1] https://en.wikipedia.org/wiki/DPLL_algorithm - -/// Boolean variables are represented as positive integers. -using Variable = uint32_t; - -/// A null boolean variable is used as a placeholder in various data structures -/// and algorithms. -static constexpr Variable NullVar = 0; - -/// Literals are represented as positive integers. Specifically, for a boolean -/// variable `V` that is represented as the positive integer `I`, the positive -/// literal `V` is represented as the integer `2*I` and the negative literal -/// `!V` is represented as the integer `2*I+1`. -using Literal = uint32_t; - -/// A null literal is used as a placeholder in various data structures and -/// algorithms. -[[maybe_unused]] static constexpr Literal NullLit = 0; - -/// Returns the positive literal `V`. -static constexpr Literal posLit(Variable V) { return 2 * V; } - -static constexpr bool isPosLit(Literal L) { return 0 == (L & 1); } - -static constexpr bool isNegLit(Literal L) { return 1 == (L & 1); } - -/// Returns the negative literal `!V`. -static constexpr Literal negLit(Variable V) { return 2 * V + 1; } - -/// Returns the negated literal `!L`. -static constexpr Literal notLit(Literal L) { return L ^ 1; } - -/// Returns the variable of `L`. -static constexpr Variable var(Literal L) { return L >> 1; } - -/// Clause identifiers are represented as positive integers. -using ClauseID = uint32_t; - -/// A null clause identifier is used as a placeholder in various data structures -/// and algorithms. -static constexpr ClauseID NullClause = 0; +namespace { -/// A boolean formula in conjunctive normal form. -struct CNFFormula { - /// `LargestVar` is equal to the largest positive integer that represents a - /// variable in the formula. - const Variable LargestVar; - - /// Literals of all clauses in the formula. - /// - /// The element at index 0 stands for the literal in the null clause. It is - /// set to 0 and isn't used. Literals of clauses in the formula start from the - /// element at index 1. - /// - /// For example, for the formula `(L1 v L2) ^ (L2 v L3 v L4)` the elements of - /// `Clauses` will be `[0, L1, L2, L2, L3, L4]`. - std::vector Clauses; +class WatchedLiteralsSolverImpl { + /// Stores the variable identifier and Atom for atomic booleans in the + /// formula. + llvm::DenseMap Atomics; - /// Start indices of clauses of the formula in `Clauses`. - /// - /// The element at index 0 stands for the start index of the null clause. It - /// is set to 0 and isn't used. Start indices of clauses in the formula start - /// from the element at index 1. - /// - /// For example, for the formula `(L1 v L2) ^ (L2 v L3 v L4)` the elements of - /// `ClauseStarts` will be `[0, 1, 3]`. Note that the literals of the first - /// clause always start at index 1. The start index for the literals of the - /// second clause depends on the size of the first clause and so on. - std::vector ClauseStarts; + /// A boolean formula in conjunctive normal form that the solver will attempt + /// to prove satisfiable. The formula will be modified in the process. + CNFFormula CNF; /// Maps literals (indices of the vector) to clause identifiers (elements of /// the vector) that watch the respective literals. @@ -127,328 +53,6 @@ struct CNFFormula { /// clauses in the formula start from the element at index 1. std::vector NextWatched; - /// Stores the variable identifier and Atom for atomic booleans in the - /// formula. - llvm::DenseMap Atomics; - - /// Indicates that we already know the formula is unsatisfiable. - /// During construction, we catch simple cases of conflicting unit-clauses. - bool KnownContradictory; - - explicit CNFFormula(Variable LargestVar, - llvm::DenseMap Atomics) - : LargestVar(LargestVar), Atomics(std::move(Atomics)), - KnownContradictory(false) { - Clauses.push_back(0); - ClauseStarts.push_back(0); - NextWatched.push_back(0); - const size_t NumLiterals = 2 * LargestVar + 1; - WatchedHead.resize(NumLiterals + 1, 0); - } - - /// Adds the `L1 v ... v Ln` clause to the formula. - /// Requirements: - /// - /// `Li` must not be `NullLit`. - /// - /// All literals in the input that are not `NullLit` must be distinct. - void addClause(ArrayRef lits) { - assert(!lits.empty()); - assert(llvm::all_of(lits, [](Literal L) { return L != NullLit; })); - - const ClauseID C = ClauseStarts.size(); - const size_t S = Clauses.size(); - ClauseStarts.push_back(S); - Clauses.insert(Clauses.end(), lits.begin(), lits.end()); - - // Designate the first literal as the "watched" literal of the clause. - NextWatched.push_back(WatchedHead[lits.front()]); - WatchedHead[lits.front()] = C; - } - - /// Returns the number of literals in clause `C`. - size_t clauseSize(ClauseID C) const { - return C == ClauseStarts.size() - 1 ? Clauses.size() - ClauseStarts[C] - : ClauseStarts[C + 1] - ClauseStarts[C]; - } - - /// Returns the literals of clause `C`. - llvm::ArrayRef clauseLiterals(ClauseID C) const { - return llvm::ArrayRef(&Clauses[ClauseStarts[C]], clauseSize(C)); - } -}; - -/// Applies simplifications while building up a BooleanFormula. -/// We keep track of unit clauses, which tell us variables that must be -/// true/false in any model that satisfies the overall formula. -/// Such variables can be dropped from subsequently-added clauses, which -/// may in turn yield more unit clauses or even a contradiction. -/// The total added complexity of this preprocessing is O(N) where we -/// for every clause, we do a lookup for each unit clauses. -/// The lookup is O(1) on average. This method won't catch all -/// contradictory formulas, more passes can in principle catch -/// more cases but we leave all these and the general case to the -/// proper SAT solver. -struct CNFFormulaBuilder { - // Formula should outlive CNFFormulaBuilder. - explicit CNFFormulaBuilder(CNFFormula &CNF) - : Formula(CNF) {} - - /// Adds the `L1 v ... v Ln` clause to the formula. Applies - /// simplifications, based on single-literal clauses. - /// - /// Requirements: - /// - /// `Li` must not be `NullLit`. - /// - /// All literals must be distinct. - void addClause(ArrayRef Literals) { - // We generate clauses with up to 3 literals in this file. - assert(!Literals.empty() && Literals.size() <= 3); - // Contains literals of the simplified clause. - llvm::SmallVector Simplified; - for (auto L : Literals) { - assert(L != NullLit && - llvm::all_of(Simplified, - [L](Literal S) { return S != L; })); - auto X = var(L); - if (trueVars.contains(X)) { // X must be true - if (isPosLit(L)) - return; // Omit clause `(... v X v ...)`, it is `true`. - else - continue; // Omit `!X` from `(... v !X v ...)`. - } - if (falseVars.contains(X)) { // X must be false - if (isNegLit(L)) - return; // Omit clause `(... v !X v ...)`, it is `true`. - else - continue; // Omit `X` from `(... v X v ...)`. - } - Simplified.push_back(L); - } - if (Simplified.empty()) { - // Simplification made the clause empty, which is equivalent to `false`. - // We already know that this formula is unsatisfiable. - Formula.KnownContradictory = true; - // We can add any of the input literals to get an unsatisfiable formula. - Formula.addClause(Literals[0]); - return; - } - if (Simplified.size() == 1) { - // We have new unit clause. - const Literal lit = Simplified.front(); - const Variable v = var(lit); - if (isPosLit(lit)) - trueVars.insert(v); - else - falseVars.insert(v); - } - Formula.addClause(Simplified); - } - - /// Returns true if we observed a contradiction while adding clauses. - /// In this case then the formula is already known to be unsatisfiable. - bool isKnownContradictory() { return Formula.KnownContradictory; } - -private: - CNFFormula &Formula; - llvm::DenseSet trueVars; - llvm::DenseSet falseVars; -}; - -/// Converts the conjunction of `Vals` into a formula in conjunctive normal -/// form where each clause has at least one and at most three literals. -CNFFormula buildCNF(const llvm::ArrayRef &Vals) { - // The general strategy of the algorithm implemented below is to map each - // of the sub-values in `Vals` to a unique variable and use these variables in - // the resulting CNF expression to avoid exponential blow up. The number of - // literals in the resulting formula is guaranteed to be linear in the number - // of sub-formulas in `Vals`. - - // Map each sub-formula in `Vals` to a unique variable. - llvm::DenseMap SubValsToVar; - // Store variable identifiers and Atom of atomic booleans. - llvm::DenseMap Atomics; - Variable NextVar = 1; - { - std::queue UnprocessedSubVals; - for (const Formula *Val : Vals) - UnprocessedSubVals.push(Val); - while (!UnprocessedSubVals.empty()) { - Variable Var = NextVar; - const Formula *Val = UnprocessedSubVals.front(); - UnprocessedSubVals.pop(); - - if (!SubValsToVar.try_emplace(Val, Var).second) - continue; - ++NextVar; - - for (const Formula *F : Val->operands()) - UnprocessedSubVals.push(F); - if (Val->kind() == Formula::AtomRef) - Atomics[Var] = Val->getAtom(); - } - } - - auto GetVar = [&SubValsToVar](const Formula *Val) { - auto ValIt = SubValsToVar.find(Val); - assert(ValIt != SubValsToVar.end()); - return ValIt->second; - }; - - CNFFormula CNF(NextVar - 1, std::move(Atomics)); - std::vector ProcessedSubVals(NextVar, false); - CNFFormulaBuilder builder(CNF); - - // Add a conjunct for each variable that represents a top-level conjunction - // value in `Vals`. - for (const Formula *Val : Vals) - builder.addClause(posLit(GetVar(Val))); - - // Add conjuncts that represent the mapping between newly-created variables - // and their corresponding sub-formulas. - std::queue UnprocessedSubVals; - for (const Formula *Val : Vals) - UnprocessedSubVals.push(Val); - while (!UnprocessedSubVals.empty()) { - const Formula *Val = UnprocessedSubVals.front(); - UnprocessedSubVals.pop(); - const Variable Var = GetVar(Val); - - if (ProcessedSubVals[Var]) - continue; - ProcessedSubVals[Var] = true; - - switch (Val->kind()) { - case Formula::AtomRef: - break; - case Formula::Literal: - CNF.addClause(Val->literal() ? posLit(Var) : negLit(Var)); - break; - case Formula::And: { - const Variable LHS = GetVar(Val->operands()[0]); - const Variable RHS = GetVar(Val->operands()[1]); - - if (LHS == RHS) { - // `X <=> (A ^ A)` is equivalent to `(!X v A) ^ (X v !A)` which is - // already in conjunctive normal form. Below we add each of the - // conjuncts of the latter expression to the result. - builder.addClause({negLit(Var), posLit(LHS)}); - builder.addClause({posLit(Var), negLit(LHS)}); - } else { - // `X <=> (A ^ B)` is equivalent to `(!X v A) ^ (!X v B) ^ (X v !A v - // !B)` which is already in conjunctive normal form. Below we add each - // of the conjuncts of the latter expression to the result. - builder.addClause({negLit(Var), posLit(LHS)}); - builder.addClause({negLit(Var), posLit(RHS)}); - builder.addClause({posLit(Var), negLit(LHS), negLit(RHS)}); - } - break; - } - case Formula::Or: { - const Variable LHS = GetVar(Val->operands()[0]); - const Variable RHS = GetVar(Val->operands()[1]); - - if (LHS == RHS) { - // `X <=> (A v A)` is equivalent to `(!X v A) ^ (X v !A)` which is - // already in conjunctive normal form. Below we add each of the - // conjuncts of the latter expression to the result. - builder.addClause({negLit(Var), posLit(LHS)}); - builder.addClause({posLit(Var), negLit(LHS)}); - } else { - // `X <=> (A v B)` is equivalent to `(!X v A v B) ^ (X v !A) ^ (X v - // !B)` which is already in conjunctive normal form. Below we add each - // of the conjuncts of the latter expression to the result. - builder.addClause({negLit(Var), posLit(LHS), posLit(RHS)}); - builder.addClause({posLit(Var), negLit(LHS)}); - builder.addClause({posLit(Var), negLit(RHS)}); - } - break; - } - case Formula::Not: { - const Variable Operand = GetVar(Val->operands()[0]); - - // `X <=> !Y` is equivalent to `(!X v !Y) ^ (X v Y)` which is - // already in conjunctive normal form. Below we add each of the - // conjuncts of the latter expression to the result. - builder.addClause({negLit(Var), negLit(Operand)}); - builder.addClause({posLit(Var), posLit(Operand)}); - break; - } - case Formula::Implies: { - const Variable LHS = GetVar(Val->operands()[0]); - const Variable RHS = GetVar(Val->operands()[1]); - - // `X <=> (A => B)` is equivalent to - // `(X v A) ^ (X v !B) ^ (!X v !A v B)` which is already in - // conjunctive normal form. Below we add each of the conjuncts of - // the latter expression to the result. - builder.addClause({posLit(Var), posLit(LHS)}); - builder.addClause({posLit(Var), negLit(RHS)}); - builder.addClause({negLit(Var), negLit(LHS), posLit(RHS)}); - break; - } - case Formula::Equal: { - const Variable LHS = GetVar(Val->operands()[0]); - const Variable RHS = GetVar(Val->operands()[1]); - - if (LHS == RHS) { - // `X <=> (A <=> A)` is equivalent to `X` which is already in - // conjunctive normal form. Below we add each of the conjuncts of the - // latter expression to the result. - builder.addClause(posLit(Var)); - - // No need to visit the sub-values of `Val`. - continue; - } - // `X <=> (A <=> B)` is equivalent to - // `(X v A v B) ^ (X v !A v !B) ^ (!X v A v !B) ^ (!X v !A v B)` which - // is already in conjunctive normal form. Below we add each of the - // conjuncts of the latter expression to the result. - builder.addClause({posLit(Var), posLit(LHS), posLit(RHS)}); - builder.addClause({posLit(Var), negLit(LHS), negLit(RHS)}); - builder.addClause({negLit(Var), posLit(LHS), negLit(RHS)}); - builder.addClause({negLit(Var), negLit(LHS), posLit(RHS)}); - break; - } - } - if (builder.isKnownContradictory()) { - return CNF; - } - for (const Formula *Child : Val->operands()) - UnprocessedSubVals.push(Child); - } - - // Unit clauses that were added later were not - // considered for the simplification of earlier clauses. Do a final - // pass to find more opportunities for simplification. - CNFFormula FinalCNF(NextVar - 1, std::move(CNF.Atomics)); - CNFFormulaBuilder FinalBuilder(FinalCNF); - - // Collect unit clauses. - for (ClauseID C = 1; C < CNF.ClauseStarts.size(); ++C) { - if (CNF.clauseSize(C) == 1) { - FinalBuilder.addClause(CNF.clauseLiterals(C)[0]); - } - } - - // Add all clauses that were added previously, preserving the order. - for (ClauseID C = 1; C < CNF.ClauseStarts.size(); ++C) { - FinalBuilder.addClause(CNF.clauseLiterals(C)); - if (FinalBuilder.isKnownContradictory()) { - break; - } - } - // It is possible there were new unit clauses again, but - // we stop here and leave the rest to the solver algorithm. - return FinalCNF; -} - -class WatchedLiteralsSolverImpl { - /// A boolean formula in conjunctive normal form that the solver will attempt - /// to prove satisfiable. The formula will be modified in the process. - CNFFormula CNF; - /// The search for a satisfying assignment of the variables in `Formula` will /// proceed in levels, starting from 1 and going up to `Formula.LargestVar` /// (inclusive). The current level is stored in `Level`. At each level the @@ -501,20 +105,37 @@ class WatchedLiteralsSolverImpl { public: explicit WatchedLiteralsSolverImpl( const llvm::ArrayRef &Vals) - : CNF(buildCNF(Vals)), LevelVars(CNF.LargestVar + 1), - LevelStates(CNF.LargestVar + 1) { + // `Atomics` needs to be initialized first so that we can use it as an + // output argument of `buildCNF()`. + : Atomics(), CNF(buildCNF(Vals, Atomics)), + LevelVars(CNF.largestVar() + 1), LevelStates(CNF.largestVar() + 1) { assert(!Vals.empty()); + // Skip initialization if the formula is known to be contradictory. + if (CNF.knownContradictory()) + return; + + // Initialize `NextWatched` and `WatchedHead`. + NextWatched.push_back(0); + const size_t NumLiterals = 2 * CNF.largestVar() + 1; + WatchedHead.resize(NumLiterals + 1, 0); + for (ClauseID C = 1; C <= CNF.numClauses(); ++C) { + // Designate the first literal as the "watched" literal of the clause. + Literal FirstLit = CNF.clauseLiterals(C).front(); + NextWatched.push_back(WatchedHead[FirstLit]); + WatchedHead[FirstLit] = C; + } + // Initialize the state at the root level to a decision so that in // `reverseForcedMoves` we don't have to check that `Level >= 0` on each // iteration. LevelStates[0] = State::Decision; // Initialize all variables as unassigned. - VarAssignments.resize(CNF.LargestVar + 1, Assignment::Unassigned); + VarAssignments.resize(CNF.largestVar() + 1, Assignment::Unassigned); // Initialize the active variables. - for (Variable Var = CNF.LargestVar; Var != NullVar; --Var) { + for (Variable Var = CNF.largestVar(); Var != NullVar; --Var) { if (isWatched(posLit(Var)) || isWatched(negLit(Var))) ActiveVars.push_back(Var); } @@ -523,7 +144,7 @@ class WatchedLiteralsSolverImpl { // Returns the `Result` and the number of iterations "remaining" from // `MaxIterations` (that is, `MaxIterations` - iterations in this call). std::pair solve(std::int64_t MaxIterations) && { - if (CNF.KnownContradictory) { + if (CNF.knownContradictory()) { // Short-cut the solving process. We already found out at CNF // construction time that the formula is unsatisfiable. return std::make_pair(Solver::Result::Unsatisfiable(), MaxIterations); @@ -625,7 +246,7 @@ class WatchedLiteralsSolverImpl { /// Returns a satisfying truth assignment to the atoms in the boolean formula. llvm::DenseMap buildSolution() { llvm::DenseMap Solution; - for (auto &Atomic : CNF.Atomics) { + for (auto &Atomic : Atomics) { // A variable may have a definite true/false assignment, or it may be // unassigned indicating its truth value does not affect the result of // the formula. Unassigned variables are assigned to true as a default. @@ -661,24 +282,25 @@ class WatchedLiteralsSolverImpl { const Literal FalseLit = VarAssignments[Var] == Assignment::AssignedTrue ? negLit(Var) : posLit(Var); - ClauseID FalseLitWatcher = CNF.WatchedHead[FalseLit]; - CNF.WatchedHead[FalseLit] = NullClause; + ClauseID FalseLitWatcher = WatchedHead[FalseLit]; + WatchedHead[FalseLit] = NullClause; while (FalseLitWatcher != NullClause) { - const ClauseID NextFalseLitWatcher = CNF.NextWatched[FalseLitWatcher]; + const ClauseID NextFalseLitWatcher = NextWatched[FalseLitWatcher]; // Pick the first non-false literal as the new watched literal. - const size_t FalseLitWatcherStart = CNF.ClauseStarts[FalseLitWatcher]; - size_t NewWatchedLitIdx = FalseLitWatcherStart + 1; - while (isCurrentlyFalse(CNF.Clauses[NewWatchedLitIdx])) - ++NewWatchedLitIdx; - const Literal NewWatchedLit = CNF.Clauses[NewWatchedLitIdx]; + const CNFFormula::Iterator FalseLitWatcherStart = + CNF.startOfClause(FalseLitWatcher); + CNFFormula::Iterator NewWatchedLitIter = FalseLitWatcherStart.next(); + while (isCurrentlyFalse(*NewWatchedLitIter)) + ++NewWatchedLitIter; + const Literal NewWatchedLit = *NewWatchedLitIter; const Variable NewWatchedLitVar = var(NewWatchedLit); // Swap the old watched literal for the new one in `FalseLitWatcher` to // maintain the invariant that the watched literal is at the beginning of // the clause. - CNF.Clauses[NewWatchedLitIdx] = FalseLit; - CNF.Clauses[FalseLitWatcherStart] = NewWatchedLit; + *NewWatchedLitIter = FalseLit; + *FalseLitWatcherStart = NewWatchedLit; // If the new watched literal isn't watched by any other clause and its // variable isn't assigned we need to add it to the active variables. @@ -686,8 +308,8 @@ class WatchedLiteralsSolverImpl { VarAssignments[NewWatchedLitVar] == Assignment::Unassigned) ActiveVars.push_back(NewWatchedLitVar); - CNF.NextWatched[FalseLitWatcher] = CNF.WatchedHead[NewWatchedLit]; - CNF.WatchedHead[NewWatchedLit] = FalseLitWatcher; + NextWatched[FalseLitWatcher] = WatchedHead[NewWatchedLit]; + WatchedHead[NewWatchedLit] = FalseLitWatcher; // Go to the next clause that watches `FalseLit`. FalseLitWatcher = NextFalseLitWatcher; @@ -697,8 +319,8 @@ class WatchedLiteralsSolverImpl { /// Returns true if and only if one of the clauses that watch `Lit` is a unit /// clause. bool watchedByUnitClause(Literal Lit) const { - for (ClauseID LitWatcher = CNF.WatchedHead[Lit]; LitWatcher != NullClause; - LitWatcher = CNF.NextWatched[LitWatcher]) { + for (ClauseID LitWatcher = WatchedHead[Lit]; LitWatcher != NullClause; + LitWatcher = NextWatched[LitWatcher]) { llvm::ArrayRef Clause = CNF.clauseLiterals(LitWatcher); // Assert the invariant that the watched literal is always the first one @@ -728,9 +350,7 @@ class WatchedLiteralsSolverImpl { } /// Returns true if and only if `Lit` is watched by a clause in `Formula`. - bool isWatched(Literal Lit) const { - return CNF.WatchedHead[Lit] != NullClause; - } + bool isWatched(Literal Lit) const { return WatchedHead[Lit] != NullClause; } /// Returns an assignment for an unassigned variable. Assignment decideAssignment(Variable Var) const { @@ -742,8 +362,8 @@ class WatchedLiteralsSolverImpl { /// Returns a set of all watched literals. llvm::DenseSet watchedLiterals() const { llvm::DenseSet WatchedLiterals; - for (Literal Lit = 2; Lit < CNF.WatchedHead.size(); Lit++) { - if (CNF.WatchedHead[Lit] == NullClause) + for (Literal Lit = 2; Lit < WatchedHead.size(); Lit++) { + if (WatchedHead[Lit] == NullClause) continue; WatchedLiterals.insert(Lit); } @@ -783,6 +403,8 @@ class WatchedLiteralsSolverImpl { } }; +} // namespace + Solver::Result WatchedLiteralsSolver::solve(llvm::ArrayRef Vals) { if (Vals.empty()) diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index 143c04309d075..1dc51deb82987 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -82,6 +82,22 @@ getDirectoryFromFile(FileManager &FileMgr, StringRef Filename, return FileMgr.getDirectoryRef(DirName, CacheFailure); } +DirectoryEntry *&FileManager::getRealDirEntry(const llvm::vfs::Status &Status) { + assert(Status.isDirectory() && "The directory should exist!"); + // See if we have already opened a directory with the + // same inode (this occurs on Unix-like systems when one dir is + // symlinked to another, for example) or the same path (on + // Windows). + DirectoryEntry *&UDE = UniqueRealDirs[Status.getUniqueID()]; + + if (!UDE) { + // We don't have this directory yet, add it. We use the string + // key from the SeenDirEntries map as the string. + UDE = new (DirsAlloc.Allocate()) DirectoryEntry(); + } + return UDE; +} + /// Add all ancestors of the given path (pointing to either a file or /// a directory) as virtual directories. void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { @@ -99,10 +115,21 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { if (NamedDirEnt.second) return; - // Add the virtual directory to the cache. - auto *UDE = new (DirsAlloc.Allocate()) DirectoryEntry(); - NamedDirEnt.second = *UDE; - VirtualDirectoryEntries.push_back(UDE); + // Check to see if the directory exists. + llvm::vfs::Status Status; + auto statError = + getStatValue(DirName, Status, false, nullptr /*directory lookup*/); + if (statError) { + // There's no real directory at the given path. + // Add the virtual directory to the cache. + auto *UDE = new (DirsAlloc.Allocate()) DirectoryEntry(); + NamedDirEnt.second = *UDE; + VirtualDirectoryEntries.push_back(UDE); + } else { + // There is the real directory + DirectoryEntry *&UDE = getRealDirEntry(Status); + NamedDirEnt.second = *UDE; + } // Recursively add the other ancestors. addAncestorsAsVirtualDirs(DirName); @@ -162,17 +189,8 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) { return llvm::errorCodeToError(statError); } - // It exists. See if we have already opened a directory with the - // same inode (this occurs on Unix-like systems when one dir is - // symlinked to another, for example) or the same path (on - // Windows). - DirectoryEntry *&UDE = UniqueRealDirs[Status.getUniqueID()]; - - if (!UDE) { - // We don't have this directory yet, add it. We use the string - // key from the SeenDirEntries map as the string. - UDE = new (DirsAlloc.Allocate()) DirectoryEntry(); - } + // It exists. + DirectoryEntry *&UDE = getRealDirEntry(Status); NamedDirEnt.second = *UDE; return DirectoryEntryRef(NamedDirEnt); diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index 3a65f53c52485..174bc9d2ab996 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -273,6 +273,34 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { Diags.Report(diag::err_mips_fp64_req) << "-mfp64"; return false; } + // FPXX requires mips2+ + if (FPMode == FPXX && CPU == "mips1") { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" << CPU; + return false; + } + // -mmsa with -msoft-float makes nonsense + if (FloatABI == SoftFloat && HasMSA) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-msoft-float" + << "-mmsa"; + return false; + } + // Option -mmsa permitted on Mips32 iff revision 2 or higher is present + if (HasMSA && (CPU == "mips1" || CPU == "mips2" || getISARev() < 2) && + ABI == "o32") { + Diags.Report(diag::err_mips_fp64_req) << "-mmsa"; + return false; + } + // MSA requires FP64 + if (FPMode == FPXX && HasMSA) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfpxx" + << "-mmsa"; + return false; + } + if (FPMode == FP32 && HasMSA) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfp32" + << "-mmsa"; + return false; + } return true; } diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index f76c6ece8bf48..b6f110249fa78 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -324,6 +324,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { FPMode = getDefaultFPMode(); bool OddSpregGiven = false; bool StrictAlign = false; + bool FpGiven = false; for (const auto &Feature : Features) { if (Feature == "+single-float") @@ -348,13 +349,16 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { HasMSA = true; else if (Feature == "+nomadd4") DisableMadd4 = true; - else if (Feature == "+fp64") + else if (Feature == "+fp64") { FPMode = FP64; - else if (Feature == "-fp64") + FpGiven = true; + } else if (Feature == "-fp64") { FPMode = FP32; - else if (Feature == "+fpxx") + FpGiven = true; + } else if (Feature == "+fpxx") { FPMode = FPXX; - else if (Feature == "+nan2008") + FpGiven = true; + } else if (Feature == "+nan2008") IsNan2008 = true; else if (Feature == "-nan2008") IsNan2008 = false; @@ -381,6 +385,11 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { if (StrictAlign) HasUnalignedAccess = false; + if (HasMSA && !FpGiven) { + FPMode = FP64; + Features.push_back("+fp64"); + } + setDataLayout(); return true; diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 4db97867df607..e4a449d1ff304 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -90,6 +90,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { StringRef getABI() const override; bool setABI(const std::string &Name) override; + bool useFP16ConversionIntrinsics() const override { + return !HasHalfPrecision; + } protected: void getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index b823eaf6ce336..3a30cff917bb4 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -310,15 +310,9 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasAVX512VNNI = true; } else if (Feature == "+avx512bf16") { HasAVX512BF16 = true; - } else if (Feature == "+avx512er") { - HasAVX512ER = true; - Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+avx512fp16") { HasAVX512FP16 = true; HasLegalHalfType = true; - } else if (Feature == "+avx512pf") { - HasAVX512PF = true; - Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+avx512dq") { HasAVX512DQ = true; } else if (Feature == "+avx512bitalg") { @@ -375,9 +369,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasWBNOINVD = true; } else if (Feature == "+prefetchi") { HasPREFETCHI = true; - } else if (Feature == "+prefetchwt1") { - HasPREFETCHWT1 = true; - Diags.Report(diag::warn_knl_knm_isa_support_removed); } else if (Feature == "+clzero") { HasCLZERO = true; } else if (Feature == "+cldemote") { @@ -840,12 +831,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512VNNI__"); if (HasAVX512BF16) Builder.defineMacro("__AVX512BF16__"); - if (HasAVX512ER) - Builder.defineMacro("__AVX512ER__"); if (HasAVX512FP16) Builder.defineMacro("__AVX512FP16__"); - if (HasAVX512PF) - Builder.defineMacro("__AVX512PF__"); if (HasAVX512DQ) Builder.defineMacro("__AVX512DQ__"); if (HasAVX512BITALG) @@ -897,8 +884,6 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__SM4__"); if (HasPREFETCHI) Builder.defineMacro("__PREFETCHI__"); - if (HasPREFETCHWT1) - Builder.defineMacro("__PREFETCHWT1__"); if (HasCLZERO) Builder.defineMacro("__CLZERO__"); if (HasKL) @@ -1084,9 +1069,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("avx512vpopcntdq", true) .Case("avx512vnni", true) .Case("avx512bf16", true) - .Case("avx512er", true) .Case("avx512fp16", true) - .Case("avx512pf", true) .Case("avx512dq", true) .Case("avx512bitalg", true) .Case("avx512bw", true) @@ -1134,7 +1117,6 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("pku", true) .Case("popcnt", true) .Case("prefetchi", true) - .Case("prefetchwt1", true) .Case("prfchw", true) .Case("ptwrite", true) .Case("raoint", true) @@ -1201,9 +1183,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ) .Case("avx512vnni", HasAVX512VNNI) .Case("avx512bf16", HasAVX512BF16) - .Case("avx512er", HasAVX512ER) .Case("avx512fp16", HasAVX512FP16) - .Case("avx512pf", HasAVX512PF) .Case("avx512dq", HasAVX512DQ) .Case("avx512bitalg", HasAVX512BITALG) .Case("avx512bw", HasAVX512BW) @@ -1253,7 +1233,6 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) .Case("prefetchi", HasPREFETCHI) - .Case("prefetchwt1", HasPREFETCHWT1) .Case("prfchw", HasPRFCHW) .Case("ptwrite", HasPTWRITE) .Case("raoint", HasRAOINT) diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 6a0a6cb84203d..0633b7e0da96a 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -103,8 +103,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasAVX512VNNI = false; bool HasAVX512FP16 = false; bool HasAVX512BF16 = false; - bool HasAVX512ER = false; - bool HasAVX512PF = false; bool HasAVX512DQ = false; bool HasAVX512BITALG = false; bool HasAVX512BW = false; @@ -136,7 +134,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasCLWB = false; bool HasMOVBE = false; bool HasPREFETCHI = false; - bool HasPREFETCHWT1 = false; bool HasRDPID = false; bool HasRDPRU = false; bool HasRetpolineExternalThunk = false; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ba94bf89e4751..5edf8c7970913 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -57,6 +57,7 @@ #include "llvm/IR/IntrinsicsX86.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/MatrixBuilder.h" +#include "llvm/IR/MemoryModelRelaxationAnnotations.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ScopedPrinter.h" @@ -18327,6 +18328,29 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, return nullptr; } +void CodeGenFunction::AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, + const CallExpr *E) { + constexpr const char *Tag = "amdgpu-as"; + + LLVMContext &Ctx = Inst->getContext(); + SmallVector MMRAs; + for (unsigned K = 2; K < E->getNumArgs(); ++K) { + llvm::Value *V = EmitScalarExpr(E->getArg(K)); + StringRef AS; + if (llvm::getConstantStringInfo(V, AS)) { + MMRAs.push_back({Tag, AS}); + // TODO: Delete the resulting unused constant? + continue; + } + CGM.Error(E->getExprLoc(), + "expected an address space name as a string literal"); + } + + llvm::sort(MMRAs); + MMRAs.erase(llvm::unique(MMRAs), MMRAs.end()); + Inst->setMetadata(LLVMContext::MD_mmra, MMRAMetadata::getMD(Ctx, MMRAs)); +} + Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { llvm::AtomicOrdering AO = llvm::AtomicOrdering::SequentiallyConsistent; @@ -18997,7 +19021,10 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_fence: { ProcessOrderScopeAMDGCN(EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), AO, SSID); - return Builder.CreateFence(AO, SSID); + FenceInst *Fence = Builder.CreateFence(AO, SSID); + if (E->getNumArgs() > 2) + AddAMDGPUFenceAddressSpaceMMRA(Fence, E); + return Fence; } case AMDGPU::BI__builtin_amdgcn_atomic_inc32: case AMDGPU::BI__builtin_amdgcn_atomic_inc64: @@ -21230,6 +21257,17 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_storef16_f32); return Builder.CreateCall(Callee, {Val, Addr}); } + case WebAssembly::BI__builtin_wasm_splat_f16x8: { + Value *Val = EmitScalarExpr(E->getArg(0)); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_splat_f16x8); + return Builder.CreateCall(Callee, {Val}); + } + case WebAssembly::BI__builtin_wasm_extract_lane_f16x8: { + Value *Vector = EmitScalarExpr(E->getArg(0)); + Value *Index = EmitScalarExpr(E->getArg(1)); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_extract_lane_f16x8); + return Builder.CreateCall(Callee, {Vector, Index}); + } case WebAssembly::BI__builtin_wasm_table_get: { assert(E->getArg(0)->getType()->isArrayType()); Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this); diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index cc626844f424d..97449a5e51e73 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5192,18 +5192,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, case ABIArgInfo::Indirect: case ABIArgInfo::IndirectAliased: { assert(NumIRArgs == 1); - if (!I->isAggregate()) { - // Make a temporary alloca to pass the argument. - RawAddress Addr = CreateMemTempWithoutCast( - I->Ty, ArgInfo.getIndirectAlign(), "indirect-arg-temp"); - - llvm::Value *Val = getAsNaturalPointerTo(Addr, I->Ty); - if (ArgHasMaybeUndefAttr) - Val = Builder.CreateFreeze(Val); - IRCallArgs[FirstIRArg] = Val; - - I->copyInto(*this, Addr); - } else { + if (I->isAggregate()) { // We want to avoid creating an unnecessary temporary+copy here; // however, we need one in three cases: // 1. If the argument is not byval, and we are required to copy the @@ -5256,28 +5245,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } } - if (NeedCopy) { - // Create an aligned temporary, and copy to it. - RawAddress AI = CreateMemTempWithoutCast( - I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); - llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty); - if (ArgHasMaybeUndefAttr) - Val = Builder.CreateFreeze(Val); - IRCallArgs[FirstIRArg] = Val; - - // Emit lifetime markers for the temporary alloca. - llvm::TypeSize ByvalTempElementSize = - CGM.getDataLayout().getTypeAllocSize(AI.getElementType()); - llvm::Value *LifetimeSize = - EmitLifetimeStart(ByvalTempElementSize, AI.getPointer()); - - // Add cleanup code to emit the end lifetime marker after the call. - if (LifetimeSize) // In case we disabled lifetime markers. - CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize); - - // Generate the copy. - I->copyInto(*this, AI); - } else { + if (!NeedCopy) { // Skip the extra memcpy call. llvm::Value *V = getAsNaturalPointerTo(Addr, I->Ty); auto *T = llvm::PointerType::get( @@ -5289,8 +5257,31 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (ArgHasMaybeUndefAttr) Val = Builder.CreateFreeze(Val); IRCallArgs[FirstIRArg] = Val; + break; } } + + // For non-aggregate args and aggregate args meeting conditions above + // we need to create an aligned temporary, and copy to it. + RawAddress AI = CreateMemTempWithoutCast( + I->Ty, ArgInfo.getIndirectAlign(), "byval-temp"); + llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty); + if (ArgHasMaybeUndefAttr) + Val = Builder.CreateFreeze(Val); + IRCallArgs[FirstIRArg] = Val; + + // Emit lifetime markers for the temporary alloca. + llvm::TypeSize ByvalTempElementSize = + CGM.getDataLayout().getTypeAllocSize(AI.getElementType()); + llvm::Value *LifetimeSize = + EmitLifetimeStart(ByvalTempElementSize, AI.getPointer()); + + // Add cleanup code to emit the end lifetime marker after the call. + if (LifetimeSize) // In case we disabled lifetime markers. + CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize); + + // Generate the copy. + I->copyInto(*this, AI); break; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index cd1c48b420382..d6478cc6835d8 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -317,8 +317,8 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, CleanupKind CleanupKind; if (Lifetime == Qualifiers::OCL_Strong) { const ValueDecl *VD = M->getExtendingDecl(); - bool Precise = - VD && isa(VD) && VD->hasAttr(); + bool Precise = isa_and_nonnull(VD) && + VD->hasAttr(); CleanupKind = CGF.getARCCleanupKind(); Destroy = Precise ? &CodeGenFunction::destroyARCStrongPrecise : &CodeGenFunction::destroyARCStrongImprecise; @@ -4180,7 +4180,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, // If the base is a vector type, then we are forming a vector element lvalue // with this subscript. - if (E->getBase()->getType()->isVectorType() && + if (E->getBase()->getType()->isSubscriptableVectorType() && !isa(E->getBase())) { // Emit the vector as an lvalue to get its address. LValue LHS = EmitLValue(E->getBase()); @@ -4676,7 +4676,8 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field, llvm::Value *ThisValue) { bool HasExplicitObjectParameter = false; - if (const auto *MD = dyn_cast_if_present(CurCodeDecl)) { + const auto *MD = dyn_cast_if_present(CurCodeDecl); + if (MD) { HasExplicitObjectParameter = MD->isExplicitObjectMemberFunction(); assert(MD->getParent()->isLambda()); assert(MD->getParent() == Field->getParent()); @@ -4693,6 +4694,17 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field, else LambdaLV = MakeAddrLValue(AddrOfExplicitObject, D->getType().getNonReferenceType()); + + // Make sure we have an lvalue to the lambda itself and not a derived class. + auto *ThisTy = D->getType().getNonReferenceType()->getAsCXXRecordDecl(); + auto *LambdaTy = cast(Field->getParent()); + if (ThisTy != LambdaTy) { + const CXXCastPath &BasePathArray = getContext().LambdaCastPaths.at(MD); + Address Base = GetAddressOfBaseClass( + LambdaLV.getAddress(), ThisTy, BasePathArray.begin(), + BasePathArray.end(), /*NullCheckValue=*/false, SourceLocation()); + LambdaLV = MakeAddrLValue(Base, QualType{LambdaTy->getTypeForDecl(), 0}); + } } else { QualType LambdaTagType = getContext().getTagDeclType(Field->getParent()); LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index eac5ef3262937..6410f9e102c90 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -142,7 +142,7 @@ class OMPTeamsScope final : public OMPLexicalScope { /// of used expression from loop statement. class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopBasedDirective &S) { - const DeclStmt *PreInits; + const Stmt *PreInits; CodeGenFunction::OMPMapVars PreCondVars; if (auto *LD = dyn_cast(&S)) { llvm::DenseSet EmittedAsPrivate; @@ -182,17 +182,34 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { } return false; }); - PreInits = cast_or_null(LD->getPreInits()); + PreInits = LD->getPreInits(); } else if (const auto *Tile = dyn_cast(&S)) { - PreInits = cast_or_null(Tile->getPreInits()); + PreInits = Tile->getPreInits(); } else if (const auto *Unroll = dyn_cast(&S)) { - PreInits = cast_or_null(Unroll->getPreInits()); + PreInits = Unroll->getPreInits(); } else { llvm_unreachable("Unknown loop-based directive kind."); } if (PreInits) { - for (const auto *I : PreInits->decls()) - CGF.EmitVarDecl(cast(*I)); + // CompoundStmts and DeclStmts are used as lists of PreInit statements and + // declarations. Since declarations must be visible in the the following + // that they initialize, unpack the ComboundStmt they are nested in. + SmallVector PreInitStmts; + if (auto *PreInitCompound = dyn_cast(PreInits)) + llvm::append_range(PreInitStmts, PreInitCompound->body()); + else + PreInitStmts.push_back(PreInits); + + for (const Stmt *S : PreInitStmts) { + // EmitStmt skips any OMPCapturedExprDecls, but needs to be emitted + // here. + if (auto *PreInitDecl = dyn_cast(S)) { + for (Decl *I : PreInitDecl->decls()) + CGF.EmitVarDecl(cast(*I)); + continue; + } + CGF.EmitStmt(S); + } } PreCondVars.restore(CGF); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5f3ee7eb943f9..45585361a4fc9 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4635,6 +4635,9 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue); + + void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, + const CallExpr *E); void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope, llvm::AtomicOrdering &AO, llvm::SyncScope::ID &SSID); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 227813ad44e8b..e4774a587707a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4150,7 +4150,7 @@ llvm::GlobalValue::LinkageTypes getMultiversionLinkage(CodeGenModule &CGM, } static FunctionDecl *createDefaultTargetVersionFrom(const FunctionDecl *FD) { - DeclContext *DeclCtx = FD->getASTContext().getTranslationUnitDecl(); + auto *DeclCtx = const_cast(FD->getDeclContext()); TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); StorageClass SC = FD->getStorageClass(); DeclarationName Name = FD->getNameInfo().getName(); @@ -5740,15 +5740,17 @@ CodeGenModule::getLLVMLinkageVarDefinition(const VarDecl *VD) { static void replaceUsesOfNonProtoConstant(llvm::Constant *old, llvm::Function *newFn) { // Fast path. - if (old->use_empty()) return; + if (old->use_empty()) + return; llvm::Type *newRetTy = newFn->getReturnType(); - SmallVector newArgs; + SmallVector newArgs; + + SmallVector callSitesToBeRemovedFromParent; for (llvm::Value::use_iterator ui = old->use_begin(), ue = old->use_end(); - ui != ue; ) { - llvm::Value::use_iterator use = ui++; // Increment before the use is erased. - llvm::User *user = use->getUser(); + ui != ue; ui++) { + llvm::User *user = ui->getUser(); // Recognize and replace uses of bitcasts. Most calls to // unprototyped functions will use bitcasts. @@ -5760,8 +5762,9 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old, // Recognize calls to the function. llvm::CallBase *callSite = dyn_cast(user); - if (!callSite) continue; - if (!callSite->isCallee(&*use)) + if (!callSite) + continue; + if (!callSite->isCallee(&*ui)) continue; // If the return types don't match exactly, then we can't @@ -5830,6 +5833,10 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old, if (callSite->getDebugLoc()) newCall->setDebugLoc(callSite->getDebugLoc()); + callSitesToBeRemovedFromParent.push_back(callSite); + } + + for (auto *callSite : callSitesToBeRemovedFromParent) { callSite->eraseFromParent(); } } diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index f4de21bac4b46..6ce2d32dd292e 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -191,6 +191,10 @@ class SourceMappingRegion { bool isBranch() const { return FalseCount.has_value(); } + bool isMCDCBranch() const { + return std::holds_alternative(MCDCParams); + } + bool isMCDCDecision() const { return std::holds_alternative(MCDCParams); } @@ -290,10 +294,36 @@ class CoverageMappingBuilder { return SM.getLocForEndOfFile(SM.getFileID(Loc)); } - /// Find out where the current file is included or macro is expanded. - SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc) { - return Loc.isMacroID() ? SM.getImmediateExpansionRange(Loc).getBegin() - : SM.getIncludeLoc(SM.getFileID(Loc)); + /// Find out where a macro is expanded. If the immediate result is a + /// , keep looking until the result isn't. Return a pair of + /// \c SourceLocation. The first object is always the begin sloc of found + /// result. The second should be checked by the caller: if it has value, it's + /// the end sloc of the found result. Otherwise the while loop didn't get + /// executed, which means the location wasn't changed and the caller has to + /// learn the end sloc from somewhere else. + std::pair> + getNonScratchExpansionLoc(SourceLocation Loc) { + std::optional EndLoc = std::nullopt; + while (Loc.isMacroID() && + SM.isWrittenInScratchSpace(SM.getSpellingLoc(Loc))) { + auto ExpansionRange = SM.getImmediateExpansionRange(Loc); + Loc = ExpansionRange.getBegin(); + EndLoc = ExpansionRange.getEnd(); + } + return std::make_pair(Loc, EndLoc); + } + + /// Find out where the current file is included or macro is expanded. If + /// \c AcceptScratch is set to false, keep looking for expansions until the + /// found sloc is not a . + SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc, + bool AcceptScratch = true) { + if (!Loc.isMacroID()) + return SM.getIncludeLoc(SM.getFileID(Loc)); + Loc = SM.getImmediateExpansionRange(Loc).getBegin(); + if (AcceptScratch) + return Loc; + return getNonScratchExpansionLoc(Loc).first; } /// Return true if \c Loc is a location in a built-in macro. @@ -340,6 +370,15 @@ class CoverageMappingBuilder { for (auto &Region : SourceRegions) { SourceLocation Loc = Region.getBeginLoc(); + // Replace Region with its definition if it is in . + auto NonScratchExpansionLoc = getNonScratchExpansionLoc(Loc); + auto EndLoc = NonScratchExpansionLoc.second; + if (EndLoc.has_value()) { + Loc = NonScratchExpansionLoc.first; + Region.setStartLoc(Loc); + Region.setEndLoc(EndLoc.value()); + } + // Replace Loc with FileLoc if it is expanded with system headers. if (!SystemHeadersCoverage && SM.isInSystemMacro(Loc)) { auto BeginLoc = SM.getSpellingLoc(Loc); @@ -472,13 +511,19 @@ class CoverageMappingBuilder { // Ignore regions from system headers unless collecting coverage from // system headers is explicitly enabled. if (!SystemHeadersCoverage && - SM.isInSystemHeader(SM.getSpellingLoc(LocStart))) + SM.isInSystemHeader(SM.getSpellingLoc(LocStart))) { + assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() && + "Don't suppress the condition in system headers"); continue; + } auto CovFileID = getCoverageFileID(LocStart); // Ignore regions that don't have a file, such as builtin macros. - if (!CovFileID) + if (!CovFileID) { + assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() && + "Don't suppress the condition in non-file regions"); continue; + } SourceLocation LocEnd = Region.getEndLoc(); assert(SM.isWrittenInSameFile(LocStart, LocEnd) && @@ -488,8 +533,11 @@ class CoverageMappingBuilder { // This not only suppresses redundant regions, but sometimes prevents // creating regions with wrong counters if, for example, a statement's // body ends at the end of a nested macro. - if (Filter.count(std::make_pair(LocStart, LocEnd))) + if (Filter.count(std::make_pair(LocStart, LocEnd))) { + assert(!Region.isMCDCBranch() && !Region.isMCDCDecision() && + "Don't suppress the condition"); continue; + } // Find the spelling locations for the mapping region. SpellingRegion SR{SM, LocStart, LocEnd}; @@ -525,7 +573,7 @@ class CoverageMappingBuilder { SourceRegionFilter Filter; for (const auto &FM : FileIDMapping) { SourceLocation ExpandedLoc = FM.second.second; - SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc); + SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc, false); if (ParentLoc.isInvalid()) continue; @@ -2223,7 +2271,8 @@ struct CounterCoverageMappingBuilder } void VisitOpaqueValueExpr(const OpaqueValueExpr* OVE) { - Visit(OVE->getSourceExpr()); + if (OVE->isUnique()) + Visit(OVE->getSourceExpr()); } }; diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 18acf7784f714..8427286dee887 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1793,6 +1793,37 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, ThisTy, VTT, VTTTy, nullptr); } +// Check if any non-inline method has the specified attribute. +template +static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD) { + for (const auto *D : RD->noload_decls()) { + if (const auto *FD = dyn_cast(D)) { + if (FD->isInlined() || FD->doesThisDeclarationHaveABody() || + FD->isPureVirtual()) + continue; + if (D->hasAttr()) + return true; + } + } + + return false; +} + +static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM, + llvm::GlobalVariable *VTable, + const CXXRecordDecl *RD) { + if (VTable->getDLLStorageClass() != + llvm::GlobalVariable::DefaultStorageClass || + RD->hasAttr() || RD->hasAttr()) + return; + + if (CGM.getVTables().isVTableExternal(RD)) { + if (CXXRecordNonInlineHasAttr(RD)) + VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + } else if (CXXRecordNonInlineHasAttr(RD)) + VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); +} + void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD) { llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits()); @@ -1818,6 +1849,9 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, if (CGM.supportsCOMDAT() && VTable->isWeakForLinker()) VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName())); + if (CGM.getTarget().hasPS4DLLImportExport()) + setVTableSelectiveDLLImportExport(CGM, VTable, RD); + // Set the right visibility. CGM.setGVProperties(VTable, RD); @@ -1905,29 +1939,6 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base, VTable->getValueType(), VTable, Indices, /*InBounds=*/true, InRange); } -// Check whether all the non-inline virtual methods for the class have the -// specified attribute. -template -static bool CXXRecordAllNonInlineVirtualsHaveAttr(const CXXRecordDecl *RD) { - bool FoundNonInlineVirtualMethodWithAttr = false; - for (const auto *D : RD->noload_decls()) { - if (const auto *FD = dyn_cast(D)) { - if (!FD->isVirtualAsWritten() || FD->isInlineSpecified() || - FD->doesThisDeclarationHaveABody()) - continue; - if (!D->hasAttr()) - return false; - FoundNonInlineVirtualMethodWithAttr = true; - } - } - - // We didn't find any non-inline virtual methods missing the attribute. We - // will return true when we found at least one non-inline virtual with the - // attribute. (This lets our caller know that the attribute needs to be - // propagated up to the vtable.) - return FoundNonInlineVirtualMethodWithAttr; -} - llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT( CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, const CXXRecordDecl *NearestVBase) { @@ -1981,26 +1992,10 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, getContext().toCharUnitsFromBits(PAlign).getAsAlign()); VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - // In MS C++ if you have a class with virtual functions in which you are using - // selective member import/export, then all virtual functions must be exported - // unless they are inline, otherwise a link error will result. To match this - // behavior, for such classes, we dllimport the vtable if it is defined - // externally and all the non-inline virtual methods are marked dllimport, and - // we dllexport the vtable if it is defined in this TU and all the non-inline - // virtual methods are marked dllexport. - if (CGM.getTarget().hasPS4DLLImportExport()) { - if ((!RD->hasAttr()) && (!RD->hasAttr())) { - if (CGM.getVTables().isVTableExternal(RD)) { - if (CXXRecordAllNonInlineVirtualsHaveAttr(RD)) - VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - } else { - if (CXXRecordAllNonInlineVirtualsHaveAttr(RD)) - VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - } - } - } - CGM.setGVProperties(VTable, RD); + if (CGM.getTarget().hasPS4DLLImportExport()) + setVTableSelectiveDLLImportExport(CGM, VTable, RD); + CGM.setGVProperties(VTable, RD); return VTable; } @@ -3285,7 +3280,7 @@ ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) { // Import the typeinfo symbol when all non-inline virtual methods are // imported. if (CGM.getTarget().hasPS4DLLImportExport()) { - if (RD && CXXRecordAllNonInlineVirtualsHaveAttr(RD)) { + if (RD && CXXRecordNonInlineHasAttr(RD)) { GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass); CGM.setDSOLocal(GV); } @@ -3938,13 +3933,13 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( // Export the typeinfo in the same circumstances as the vtable is exported. auto GVDLLStorageClass = DLLStorageClass; - if (CGM.getTarget().hasPS4DLLImportExport()) { + if (CGM.getTarget().hasPS4DLLImportExport() && + GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) { if (const RecordType *RecordTy = dyn_cast(Ty)) { const CXXRecordDecl *RD = cast(RecordTy->getDecl()); if (RD->hasAttr() || - CXXRecordAllNonInlineVirtualsHaveAttr(RD)) { + CXXRecordNonInlineHasAttr(RD)) GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass; - } } } @@ -3984,9 +3979,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( CGM.setDSOLocal(GV); TypeName->setDLLStorageClass(DLLStorageClass); - GV->setDLLStorageClass(CGM.getTarget().hasPS4DLLImportExport() - ? GVDLLStorageClass - : DLLStorageClass); + GV->setDLLStorageClass(GVDLLStorageClass); TypeName->setPartition(CGM.getCodeGenOpts().SymbolPartition); GV->setPartition(CGM.getCodeGenOpts().SymbolPartition); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 2868b4f2b02e9..f5ea73a04ae5c 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2653,22 +2653,13 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Diag(clang::diag::note_drv_t_option_is_global); } - // CUDA/HIP and their preprocessor expansions can be accepted by CL mode. // Warn -x after last input file has no effect - auto LastXArg = Args.getLastArgValue(options::OPT_x); - const llvm::StringSet<> ValidXArgs = {"cuda", "hip", "cui", "hipi"}; - if (!IsCLMode() || ValidXArgs.contains(LastXArg)) { + { Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x); Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT); if (LastXArg && LastInputArg && LastInputArg->getIndex() < LastXArg->getIndex()) Diag(clang::diag::warn_drv_unused_x) << LastXArg->getValue(); - } else { - // In CL mode suggest /TC or /TP since -x doesn't make sense if passed via - // /clang:. - if (auto *A = Args.getLastArg(options::OPT_x)) - Diag(diag::err_drv_unsupported_opt_with_suggestion) - << A->getAsString(Args) << "/TC' or '/TP"; } for (Arg *A : Args) { diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index 85825e1ea65b1..381d72e045b95 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -479,14 +479,6 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args, return false; }(); - // Currently only supported for small code model. - if (TOCDataGloballyinEffect && - (Args.getLastArgValue(options::OPT_mcmodel_EQ) == "large" || - Args.getLastArgValue(options::OPT_mcmodel_EQ) == "medium")) { - D.Diag(clang::diag::warn_drv_unsupported_tocdata); - return; - } - enum TOCDataSetting { AddressInTOC = 0, // Address of the symbol stored in the TOC. DataInTOC = 1 // Symbol defined in the TOC. diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index d23f9b36efb9a..9ea4cc3f7cb95 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -181,7 +181,7 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, // -m*-float and -mfpu=none/0/32 conflict with -mlsx. if (A->getOption().matches(options::OPT_mlsx)) { if (llvm::find(Features, "-d") != Features.end()) - D.Diag(diag::err_drv_loongarch_wrong_fpu_width_for_lsx); + D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LSX*/ 0; else /*-mlsx*/ Features.push_back("+lsx"); } else /*-mno-lsx*/ { @@ -196,7 +196,7 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, // -mno-lsx conflicts with -mlasx. if (A->getOption().matches(options::OPT_mlasx)) { if (llvm::find(Features, "-d") != Features.end()) - D.Diag(diag::err_drv_loongarch_wrong_fpu_width_for_lasx); + D.Diag(diag::err_drv_loongarch_wrong_fpu_width) << /*LASX*/ 1; else if (llvm::find(Features, "-lsx") != Features.end()) D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination); else { /*-mlasx*/ diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 6d2015b2cd156..97e451cfe2acb 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1030,7 +1030,7 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, // If user provided -o, that is the dependency target, except // when we are only generating a dependency file. - Arg *OutputOpt = Args.getLastArg(options::OPT_o); + Arg *OutputOpt = Args.getLastArg(options::OPT_o, options::OPT__SLASH_Fo); if (OutputOpt && Output.getType() != types::TY_Dependencies) { DepTarget = OutputOpt->getValue(); } else { @@ -5681,11 +5681,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // enabled. This alias option is being used to simplify the hasFlag logic. OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast : options::OPT_fstrict_aliasing; - // We turn strict aliasing off by default if we're in CL mode, since MSVC + // We turn strict aliasing off by default if we're Windows MSVC since MSVC // doesn't do any TBAA. - bool TBAAOnByDefault = !D.IsCLMode(); if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, - options::OPT_fno_strict_aliasing, TBAAOnByDefault)) + options::OPT_fno_strict_aliasing, !IsWindowsMSVC)) CmdArgs.push_back("-relaxed-aliasing"); if (!Args.hasFlag(options::OPT_fstruct_path_tbaa, options::OPT_fno_struct_path_tbaa, true)) @@ -7027,8 +7026,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fms_compatibility, options::OPT_fno_ms_compatibility, (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, true))); - if (IsMSVCCompat) + if (IsMSVCCompat) { CmdArgs.push_back("-fms-compatibility"); + if (!types::isCXX(Input.getType()) && + Args.hasArg(options::OPT_fms_define_stdc)) + CmdArgs.push_back("-fms-define-stdc"); + } if (Triple.isWindowsMSVCEnvironment() && !D.IsCLMode() && Args.hasArg(options::OPT_fms_runtime_lib_EQ)) @@ -7263,10 +7266,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } - // -fsized-deallocation is off by default, as it is an ABI-breaking change for - // most platforms. - Args.addOptInFlag(CmdArgs, options::OPT_fsized_deallocation, - options::OPT_fno_sized_deallocation); + // -fsized-deallocation is on by default in C++14 onwards and otherwise off + // by default. + Args.addLastArg(CmdArgs, options::OPT_fsized_deallocation, + options::OPT_fno_sized_deallocation); // -faligned-allocation is on by default in C++17 onwards and otherwise off // by default. diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index caf6c4a444fdc..593b403a1e3f0 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2912,9 +2912,54 @@ static bool sdkSupportsBuiltinModules(const Darwin::DarwinPlatformKind &TargetPl } } -void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args, - Action::OffloadKind DeviceOffloadKind) const { +static inline llvm::VersionTuple +sizedDeallocMinVersion(llvm::Triple::OSType OS) { + switch (OS) { + default: + break; + case llvm::Triple::Darwin: + case llvm::Triple::MacOSX: // Earliest supporting version is 10.12. + return llvm::VersionTuple(10U, 12U); + case llvm::Triple::IOS: + case llvm::Triple::TvOS: // Earliest supporting version is 10.0.0. + return llvm::VersionTuple(10U); + case llvm::Triple::WatchOS: // Earliest supporting version is 3.0.0. + return llvm::VersionTuple(3U); + } + + llvm_unreachable("Unexpected OS"); +} + +bool Darwin::isSizedDeallocationUnavailable() const { + llvm::Triple::OSType OS; + + if (isTargetMacCatalyst()) + return TargetVersion < sizedDeallocMinVersion(llvm::Triple::MacOSX); + switch (TargetPlatform) { + case MacOS: // Earlier than 10.12. + OS = llvm::Triple::MacOSX; + break; + case IPhoneOS: + OS = llvm::Triple::IOS; + break; + case TvOS: // Earlier than 10.0. + OS = llvm::Triple::TvOS; + break; + case WatchOS: // Earlier than 3.0. + OS = llvm::Triple::WatchOS; + break; + case DriverKit: + case XROS: + // Always available. + return false; + } + + return TargetVersion < sizedDeallocMinVersion(OS); +} + +void Darwin::addClangTargetOptions( + const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadKind) const { // Pass "-faligned-alloc-unavailable" only when the user hasn't manually // enabled or disabled aligned allocations. if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, @@ -2922,6 +2967,13 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, isAlignedAllocationUnavailable()) CC1Args.push_back("-faligned-alloc-unavailable"); + // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled + // or disabled sized deallocations. + if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation, + options::OPT_fno_sized_deallocation) && + isSizedDeallocationUnavailable()) + CC1Args.push_back("-fno-sized-deallocation"); + addClangCC1ASTargetOptions(DriverArgs, CC1Args); // Enable compatibility mode for NSItemProviderCompletionHandler in diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 10d4b69e5d5f1..b45279ecedeb2 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -511,6 +511,10 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { /// targeting. bool isAlignedAllocationUnavailable() const; + /// Return true if c++14 sized deallocation functions are not implemented in + /// the c++ standard library of the deployment target we are targeting. + bool isSizedDeallocationUnavailable() const; + void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp index a144b28057f4c..bdbcf9109129d 100644 --- a/clang/lib/Driver/ToolChains/HIPSPV.cpp +++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp @@ -193,7 +193,7 @@ void HIPSPVToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, StringRef hipPath = DriverArgs.getLastArgValue(options::OPT_hip_path_EQ); if (hipPath.empty()) { - getDriver().Diag(diag::err_drv_hipspv_no_hip_path) << 1 << "'-nogpuinc'"; + getDriver().Diag(diag::err_drv_hipspv_no_hip_path); return; } SmallString<128> P(hipPath); diff --git a/clang/lib/Driver/ToolChains/ZOS.cpp b/clang/lib/Driver/ToolChains/ZOS.cpp index d5fc7b8ef562a..074e0556ecd2a 100644 --- a/clang/lib/Driver/ToolChains/ZOS.cpp +++ b/clang/lib/Driver/ToolChains/ZOS.cpp @@ -36,6 +36,12 @@ void ZOS::addClangTargetOptions(const ArgList &DriverArgs, if (!DriverArgs.hasArgNoClaim(options::OPT_faligned_allocation, options::OPT_fno_aligned_allocation)) CC1Args.push_back("-faligned-alloc-unavailable"); + + // Pass "-fno-sized-deallocation" only when the user hasn't manually enabled + // or disabled sized deallocations. + if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation, + options::OPT_fno_sized_deallocation)) + CC1Args.push_back("-fno-sized-deallocation"); } void zos::Assembler::ConstructJob(Compilation &C, const JobAction &JA, diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 98b9343924a83..8c7c0f8a14726 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -999,11 +999,11 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( DeclarationFragments::FragmentKind::GenericParameter); if (TemplateParam->hasDefaultArgument()) { - DeclarationFragments After; + const auto Default = TemplateParam->getDefaultArgument(); Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) - .append(getFragmentsForType(TemplateParam->getDefaultArgument(), - TemplateParam->getASTContext(), After)); - Fragments.append(std::move(After)); + .append(getFragmentsForTemplateArguments( + {Default.getArgument()}, TemplateParam->getASTContext(), + {Default})); } } else if (const auto *NTP = dyn_cast(ParameterArray[i])) { @@ -1023,8 +1023,9 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( if (NTP->hasDefaultArgument()) { SmallString<8> ExprStr; raw_svector_ostream Output(ExprStr); - NTP->getDefaultArgument()->printPretty( - Output, nullptr, NTP->getASTContext().getPrintingPolicy()); + NTP->getDefaultArgument().getArgument().print( + NTP->getASTContext().getPrintingPolicy(), Output, + /*IncludeType=*/false); Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) .append(ExprStr, DeclarationFragments::FragmentKind::Text); } @@ -1083,12 +1084,22 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( if (StringRef(ArgumentFragment.begin()->Spelling) .starts_with("type-parameter")) { - std::string ProperArgName = TemplateArgumentLocs.value()[i] - .getTypeSourceInfo() - ->getType() - .getAsString(); - ArgumentFragment.begin()->Spelling.swap(ProperArgName); + if (TemplateArgumentLocs.has_value() && + TemplateArgumentLocs->size() > i) { + std::string ProperArgName = TemplateArgumentLocs.value()[i] + .getTypeSourceInfo() + ->getType() + .getAsString(); + ArgumentFragment.begin()->Spelling.swap(ProperArgName); + } else { + auto &Spelling = ArgumentFragment.begin()->Spelling; + Spelling.clear(); + raw_string_ostream OutStream(Spelling); + CTA.print(Context.getPrintingPolicy(), OutStream, false); + OutStream.flush(); + } } + Fragments.append(std::move(ArgumentFragment)); break; } @@ -1211,9 +1222,9 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( cast(Decl))) .pop_back() // there is an extra semicolon now .append("<", DeclarationFragments::FragmentKind::Text) - .append( - getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), - Decl->getASTContext(), std::nullopt)) + .append(getFragmentsForTemplateArguments( + Decl->getTemplateArgs().asArray(), Decl->getASTContext(), + Decl->getTemplateArgsAsWritten()->arguments())) .append(">", DeclarationFragments::FragmentKind::Text) .appendSemicolon(); } @@ -1254,9 +1265,9 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) .pop_back() // there is an extra semicolon now .append("<", DeclarationFragments::FragmentKind::Text) - .append( - getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), - Decl->getASTContext(), std::nullopt)) + .append(getFragmentsForTemplateArguments( + Decl->getTemplateArgs().asArray(), Decl->getASTContext(), + Decl->getTemplateArgsAsWritten()->arguments())) .append(">", DeclarationFragments::FragmentKind::Text) .appendSemicolon(); } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index b15a87327240b..b6f7567adc140 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1189,12 +1189,6 @@ void UnwrappedLineParser::parsePPDefine() { return; } - if (FormatTok->is(tok::identifier) && - Tokens->peekNextToken()->is(tok::colon)) { - nextToken(); - nextToken(); - } - // Errors during a preprocessor directive can only affect the layout of the // preprocessor directive, and thus we ignore them. An alternative approach // would be to use the same approach we use on the file level (no @@ -1416,6 +1410,13 @@ void UnwrappedLineParser::readTokenWithJavaScriptASI() { } } +static bool isAltOperator(const FormatToken &Tok) { + return isalpha(Tok.TokenText[0]) && + Tok.isOneOf(tok::ampamp, tok::ampequal, tok::amp, tok::pipe, + tok::tilde, tok::exclaim, tok::exclaimequal, tok::pipepipe, + tok::pipeequal, tok::caret, tok::caretequal); +} + void UnwrappedLineParser::parseStructuralElement( const FormatToken *OpeningBrace, IfStmtKind *IfKind, FormatToken **IfLeftBrace, bool *HasDoWhile, bool *HasLabel) { @@ -1681,7 +1682,8 @@ void UnwrappedLineParser::parseStructuralElement( if (!Style.isJavaScript() && !Style.isVerilog() && !Style.isTableGen() && Tokens->peekNextToken()->is(tok::colon) && !Line->MustBeDeclaration) { nextToken(); - Line->Tokens.begin()->Tok->MustBreakBefore = true; + if (!Line->InMacroBody || CurrentLines->size() > 1) + Line->Tokens.begin()->Tok->MustBreakBefore = true; FormatTok->setFinalizedType(TT_GotoLabelColon); parseLabel(!Style.IndentGotoLabels); if (HasLabel) @@ -1694,9 +1696,15 @@ void UnwrappedLineParser::parseStructuralElement( break; } - const bool InRequiresExpression = - OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace); - do { + for (const bool InRequiresExpression = + OpeningBrace && OpeningBrace->is(TT_RequiresExpressionLBrace); + !eof();) { + if (IsCpp && isAltOperator(*FormatTok)) { + if (auto *Next = Tokens->peekNextToken(/*SkipComment=*/true); + Next && Next->isBinaryOperator()) { + FormatTok->Tok.setKind(tok::identifier); + } + } const FormatToken *Previous = FormatTok->Previous; switch (FormatTok->Tok.getKind()) { case tok::at: @@ -2127,7 +2135,7 @@ void UnwrappedLineParser::parseStructuralElement( nextToken(); break; } - } while (!eof()); + } } bool UnwrappedLineParser::tryToParsePropertyAccessor() { diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 68760e00003e0..e8c8a5175f8f4 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -432,7 +432,8 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, // [C++] Whether __STDC__ is predefined and if so, what its value is, // are implementation-defined. // (Removed in C++20.) - if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP) + if ((!LangOpts.MSVCCompat || LangOpts.MSVCEnableStdcMacro) && + !LangOpts.TraditionalCPP) Builder.defineMacro("__STDC__"); // -- __STDC_HOSTED__ // The integer literal 1 if the implementation is a hosted diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index b76728acb9077..0887b5a504f05 100644 --- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -574,7 +574,7 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, SmallString<256> diagnostic; Info.FormatDiagnostic(diagnostic); getMetaDiags()->Report( - diag::warn_fe_serialized_diag_failure_during_finalisation) + diag::warn_fe_serialized_diag_failure_during_finalization) << diagnostic; return; } diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 5f02c71f6ca51..d3090e488306f 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -153,12 +153,10 @@ set(x86_files avx512bwintrin.h avx512cdintrin.h avx512dqintrin.h - avx512erintrin.h avx512fintrin.h avx512fp16intrin.h avx512ifmaintrin.h avx512ifmavlintrin.h - avx512pfintrin.h avx512vbmi2intrin.h avx512vbmiintrin.h avx512vbmivlintrin.h @@ -445,14 +443,14 @@ endforeach( f ) function(add_header_target target_name file_list) add_library(${target_name} INTERFACE ${file_list}) set_target_properties(${target_name} PROPERTIES - FOLDER "Misc" + FOLDER "Clang/Resources" RUNTIME_OUTPUT_DIRECTORY "${output_dir}") endfunction() # The catch-all clang-resource-headers target add_library(clang-resource-headers INTERFACE ${out_files}) set_target_properties("clang-resource-headers" PROPERTIES - FOLDER "Misc" + FOLDER "Clang/Resources" RUNTIME_OUTPUT_DIRECTORY "${output_dir}") add_dependencies("clang-resource-headers" "core-resource-headers" diff --git a/clang/lib/Headers/avx512erintrin.h b/clang/lib/Headers/avx512erintrin.h deleted file mode 100644 index 1c5a2d2d208ff..0000000000000 --- a/clang/lib/Headers/avx512erintrin.h +++ /dev/null @@ -1,271 +0,0 @@ -/*===---- avx512erintrin.h - AVX512ER intrinsics ---------------------------=== - * - * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - * See https://llvm.org/LICENSE.txt for license information. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - * - *===-----------------------------------------------------------------------=== - */ -#ifndef __IMMINTRIN_H -#error "Never use directly; include instead." -#endif - -#ifndef __AVX512ERINTRIN_H -#define __AVX512ERINTRIN_H - -/* exp2a23 */ -#define _mm512_exp2a23_round_pd(A, R) \ - ((__m512d)__builtin_ia32_exp2pd_mask((__v8df)(__m512d)(A), \ - (__v8df)_mm512_setzero_pd(), \ - (__mmask8)-1, (int)(R))) - -#define _mm512_mask_exp2a23_round_pd(S, M, A, R) \ - ((__m512d)__builtin_ia32_exp2pd_mask((__v8df)(__m512d)(A), \ - (__v8df)(__m512d)(S), (__mmask8)(M), \ - (int)(R))) - -#define _mm512_maskz_exp2a23_round_pd(M, A, R) \ - ((__m512d)__builtin_ia32_exp2pd_mask((__v8df)(__m512d)(A), \ - (__v8df)_mm512_setzero_pd(), \ - (__mmask8)(M), (int)(R))) - -#define _mm512_exp2a23_pd(A) \ - _mm512_exp2a23_round_pd((A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_mask_exp2a23_pd(S, M, A) \ - _mm512_mask_exp2a23_round_pd((S), (M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_maskz_exp2a23_pd(M, A) \ - _mm512_maskz_exp2a23_round_pd((M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_exp2a23_round_ps(A, R) \ - ((__m512)__builtin_ia32_exp2ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)_mm512_setzero_ps(), \ - (__mmask16)-1, (int)(R))) - -#define _mm512_mask_exp2a23_round_ps(S, M, A, R) \ - ((__m512)__builtin_ia32_exp2ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)(__m512)(S), (__mmask16)(M), \ - (int)(R))) - -#define _mm512_maskz_exp2a23_round_ps(M, A, R) \ - ((__m512)__builtin_ia32_exp2ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)_mm512_setzero_ps(), \ - (__mmask16)(M), (int)(R))) - -#define _mm512_exp2a23_ps(A) \ - _mm512_exp2a23_round_ps((A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_mask_exp2a23_ps(S, M, A) \ - _mm512_mask_exp2a23_round_ps((S), (M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_maskz_exp2a23_ps(M, A) \ - _mm512_maskz_exp2a23_round_ps((M), (A), _MM_FROUND_CUR_DIRECTION) - -/* rsqrt28 */ -#define _mm512_rsqrt28_round_pd(A, R) \ - ((__m512d)__builtin_ia32_rsqrt28pd_mask((__v8df)(__m512d)(A), \ - (__v8df)_mm512_setzero_pd(), \ - (__mmask8)-1, (int)(R))) - -#define _mm512_mask_rsqrt28_round_pd(S, M, A, R) \ - ((__m512d)__builtin_ia32_rsqrt28pd_mask((__v8df)(__m512d)(A), \ - (__v8df)(__m512d)(S), (__mmask8)(M), \ - (int)(R))) - -#define _mm512_maskz_rsqrt28_round_pd(M, A, R) \ - ((__m512d)__builtin_ia32_rsqrt28pd_mask((__v8df)(__m512d)(A), \ - (__v8df)_mm512_setzero_pd(), \ - (__mmask8)(M), (int)(R))) - -#define _mm512_rsqrt28_pd(A) \ - _mm512_rsqrt28_round_pd((A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_mask_rsqrt28_pd(S, M, A) \ - _mm512_mask_rsqrt28_round_pd((S), (M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_maskz_rsqrt28_pd(M, A) \ - _mm512_maskz_rsqrt28_round_pd((M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_rsqrt28_round_ps(A, R) \ - ((__m512)__builtin_ia32_rsqrt28ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)_mm512_setzero_ps(), \ - (__mmask16)-1, (int)(R))) - -#define _mm512_mask_rsqrt28_round_ps(S, M, A, R) \ - ((__m512)__builtin_ia32_rsqrt28ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)(__m512)(S), (__mmask16)(M), \ - (int)(R))) - -#define _mm512_maskz_rsqrt28_round_ps(M, A, R) \ - ((__m512)__builtin_ia32_rsqrt28ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)_mm512_setzero_ps(), \ - (__mmask16)(M), (int)(R))) - -#define _mm512_rsqrt28_ps(A) \ - _mm512_rsqrt28_round_ps((A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_mask_rsqrt28_ps(S, M, A) \ - _mm512_mask_rsqrt28_round_ps((S), (M), A, _MM_FROUND_CUR_DIRECTION) - -#define _mm512_maskz_rsqrt28_ps(M, A) \ - _mm512_maskz_rsqrt28_round_ps((M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm_rsqrt28_round_ss(A, B, R) \ - ((__m128)__builtin_ia32_rsqrt28ss_round_mask((__v4sf)(__m128)(A), \ - (__v4sf)(__m128)(B), \ - (__v4sf)_mm_setzero_ps(), \ - (__mmask8)-1, (int)(R))) - -#define _mm_mask_rsqrt28_round_ss(S, M, A, B, R) \ - ((__m128)__builtin_ia32_rsqrt28ss_round_mask((__v4sf)(__m128)(A), \ - (__v4sf)(__m128)(B), \ - (__v4sf)(__m128)(S), \ - (__mmask8)(M), (int)(R))) - -#define _mm_maskz_rsqrt28_round_ss(M, A, B, R) \ - ((__m128)__builtin_ia32_rsqrt28ss_round_mask((__v4sf)(__m128)(A), \ - (__v4sf)(__m128)(B), \ - (__v4sf)_mm_setzero_ps(), \ - (__mmask8)(M), (int)(R))) - -#define _mm_rsqrt28_ss(A, B) \ - _mm_rsqrt28_round_ss((A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_mask_rsqrt28_ss(S, M, A, B) \ - _mm_mask_rsqrt28_round_ss((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_maskz_rsqrt28_ss(M, A, B) \ - _mm_maskz_rsqrt28_round_ss((M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_rsqrt28_round_sd(A, B, R) \ - ((__m128d)__builtin_ia32_rsqrt28sd_round_mask((__v2df)(__m128d)(A), \ - (__v2df)(__m128d)(B), \ - (__v2df)_mm_setzero_pd(), \ - (__mmask8)-1, (int)(R))) - -#define _mm_mask_rsqrt28_round_sd(S, M, A, B, R) \ - ((__m128d)__builtin_ia32_rsqrt28sd_round_mask((__v2df)(__m128d)(A), \ - (__v2df)(__m128d)(B), \ - (__v2df)(__m128d)(S), \ - (__mmask8)(M), (int)(R))) - -#define _mm_maskz_rsqrt28_round_sd(M, A, B, R) \ - ((__m128d)__builtin_ia32_rsqrt28sd_round_mask((__v2df)(__m128d)(A), \ - (__v2df)(__m128d)(B), \ - (__v2df)_mm_setzero_pd(), \ - (__mmask8)(M), (int)(R))) - -#define _mm_rsqrt28_sd(A, B) \ - _mm_rsqrt28_round_sd((A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_mask_rsqrt28_sd(S, M, A, B) \ - _mm_mask_rsqrt28_round_sd((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_maskz_rsqrt28_sd(M, A, B) \ - _mm_maskz_rsqrt28_round_sd((M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -/* rcp28 */ -#define _mm512_rcp28_round_pd(A, R) \ - ((__m512d)__builtin_ia32_rcp28pd_mask((__v8df)(__m512d)(A), \ - (__v8df)_mm512_setzero_pd(), \ - (__mmask8)-1, (int)(R))) - -#define _mm512_mask_rcp28_round_pd(S, M, A, R) \ - ((__m512d)__builtin_ia32_rcp28pd_mask((__v8df)(__m512d)(A), \ - (__v8df)(__m512d)(S), (__mmask8)(M), \ - (int)(R))) - -#define _mm512_maskz_rcp28_round_pd(M, A, R) \ - ((__m512d)__builtin_ia32_rcp28pd_mask((__v8df)(__m512d)(A), \ - (__v8df)_mm512_setzero_pd(), \ - (__mmask8)(M), (int)(R))) - -#define _mm512_rcp28_pd(A) \ - _mm512_rcp28_round_pd((A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_mask_rcp28_pd(S, M, A) \ - _mm512_mask_rcp28_round_pd((S), (M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_maskz_rcp28_pd(M, A) \ - _mm512_maskz_rcp28_round_pd((M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_rcp28_round_ps(A, R) \ - ((__m512)__builtin_ia32_rcp28ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)_mm512_setzero_ps(), \ - (__mmask16)-1, (int)(R))) - -#define _mm512_mask_rcp28_round_ps(S, M, A, R) \ - ((__m512)__builtin_ia32_rcp28ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)(__m512)(S), (__mmask16)(M), \ - (int)(R))) - -#define _mm512_maskz_rcp28_round_ps(M, A, R) \ - ((__m512)__builtin_ia32_rcp28ps_mask((__v16sf)(__m512)(A), \ - (__v16sf)_mm512_setzero_ps(), \ - (__mmask16)(M), (int)(R))) - -#define _mm512_rcp28_ps(A) \ - _mm512_rcp28_round_ps((A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_mask_rcp28_ps(S, M, A) \ - _mm512_mask_rcp28_round_ps((S), (M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm512_maskz_rcp28_ps(M, A) \ - _mm512_maskz_rcp28_round_ps((M), (A), _MM_FROUND_CUR_DIRECTION) - -#define _mm_rcp28_round_ss(A, B, R) \ - ((__m128)__builtin_ia32_rcp28ss_round_mask((__v4sf)(__m128)(A), \ - (__v4sf)(__m128)(B), \ - (__v4sf)_mm_setzero_ps(), \ - (__mmask8)-1, (int)(R))) - -#define _mm_mask_rcp28_round_ss(S, M, A, B, R) \ - ((__m128)__builtin_ia32_rcp28ss_round_mask((__v4sf)(__m128)(A), \ - (__v4sf)(__m128)(B), \ - (__v4sf)(__m128)(S), \ - (__mmask8)(M), (int)(R))) - -#define _mm_maskz_rcp28_round_ss(M, A, B, R) \ - ((__m128)__builtin_ia32_rcp28ss_round_mask((__v4sf)(__m128)(A), \ - (__v4sf)(__m128)(B), \ - (__v4sf)_mm_setzero_ps(), \ - (__mmask8)(M), (int)(R))) - -#define _mm_rcp28_ss(A, B) \ - _mm_rcp28_round_ss((A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_mask_rcp28_ss(S, M, A, B) \ - _mm_mask_rcp28_round_ss((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_maskz_rcp28_ss(M, A, B) \ - _mm_maskz_rcp28_round_ss((M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_rcp28_round_sd(A, B, R) \ - ((__m128d)__builtin_ia32_rcp28sd_round_mask((__v2df)(__m128d)(A), \ - (__v2df)(__m128d)(B), \ - (__v2df)_mm_setzero_pd(), \ - (__mmask8)-1, (int)(R))) - -#define _mm_mask_rcp28_round_sd(S, M, A, B, R) \ - ((__m128d)__builtin_ia32_rcp28sd_round_mask((__v2df)(__m128d)(A), \ - (__v2df)(__m128d)(B), \ - (__v2df)(__m128d)(S), \ - (__mmask8)(M), (int)(R))) - -#define _mm_maskz_rcp28_round_sd(M, A, B, R) \ - ((__m128d)__builtin_ia32_rcp28sd_round_mask((__v2df)(__m128d)(A), \ - (__v2df)(__m128d)(B), \ - (__v2df)_mm_setzero_pd(), \ - (__mmask8)(M), (int)(R))) - -#define _mm_rcp28_sd(A, B) \ - _mm_rcp28_round_sd((A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_mask_rcp28_sd(S, M, A, B) \ - _mm_mask_rcp28_round_sd((S), (M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#define _mm_maskz_rcp28_sd(M, A, B) \ - _mm_maskz_rcp28_round_sd((M), (A), (B), _MM_FROUND_CUR_DIRECTION) - -#endif /* __AVX512ERINTRIN_H */ diff --git a/clang/lib/Headers/avx512pfintrin.h b/clang/lib/Headers/avx512pfintrin.h deleted file mode 100644 index f853be021a2dd..0000000000000 --- a/clang/lib/Headers/avx512pfintrin.h +++ /dev/null @@ -1,92 +0,0 @@ -/*===------------- avx512pfintrin.h - PF intrinsics ------------------------=== - * - * - * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. - * See https://llvm.org/LICENSE.txt for license information. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - * - *===-----------------------------------------------------------------------=== - */ -#ifndef __IMMINTRIN_H -#error "Never use directly; include instead." -#endif - -#ifndef __AVX512PFINTRIN_H -#define __AVX512PFINTRIN_H - -#define _mm512_mask_prefetch_i32gather_pd(index, mask, addr, scale, hint) \ - __builtin_ia32_gatherpfdpd((__mmask8)(mask), (__v8si)(__m256i)(index), \ - (void const *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_prefetch_i32gather_pd(index, addr, scale, hint) \ - __builtin_ia32_gatherpfdpd((__mmask8) -1, (__v8si)(__m256i)(index), \ - (void const *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_mask_prefetch_i32gather_ps(index, mask, addr, scale, hint) \ - __builtin_ia32_gatherpfdps((__mmask16)(mask), \ - (__v16si)(__m512i)(index), (void const *)(addr), \ - (int)(scale), (int)(hint)) - -#define _mm512_prefetch_i32gather_ps(index, addr, scale, hint) \ - __builtin_ia32_gatherpfdps((__mmask16) -1, \ - (__v16si)(__m512i)(index), (void const *)(addr), \ - (int)(scale), (int)(hint)) - -#define _mm512_mask_prefetch_i64gather_pd(index, mask, addr, scale, hint) \ - __builtin_ia32_gatherpfqpd((__mmask8)(mask), (__v8di)(__m512i)(index), \ - (void const *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_prefetch_i64gather_pd(index, addr, scale, hint) \ - __builtin_ia32_gatherpfqpd((__mmask8) -1, (__v8di)(__m512i)(index), \ - (void const *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_mask_prefetch_i64gather_ps(index, mask, addr, scale, hint) \ - __builtin_ia32_gatherpfqps((__mmask8)(mask), (__v8di)(__m512i)(index), \ - (void const *)(addr), (int)(scale), (int)(hint)) - -#define _mm512_prefetch_i64gather_ps(index, addr, scale, hint) \ - __builtin_ia32_gatherpfqps((__mmask8) -1, (__v8di)(__m512i)(index), \ - (void const *)(addr), (int)(scale), (int)(hint)) - -#define _mm512_prefetch_i32scatter_pd(addr, index, scale, hint) \ - __builtin_ia32_scatterpfdpd((__mmask8)-1, (__v8si)(__m256i)(index), \ - (void *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_mask_prefetch_i32scatter_pd(addr, mask, index, scale, hint) \ - __builtin_ia32_scatterpfdpd((__mmask8)(mask), (__v8si)(__m256i)(index), \ - (void *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_prefetch_i32scatter_ps(addr, index, scale, hint) \ - __builtin_ia32_scatterpfdps((__mmask16)-1, (__v16si)(__m512i)(index), \ - (void *)(addr), (int)(scale), (int)(hint)) - -#define _mm512_mask_prefetch_i32scatter_ps(addr, mask, index, scale, hint) \ - __builtin_ia32_scatterpfdps((__mmask16)(mask), \ - (__v16si)(__m512i)(index), (void *)(addr), \ - (int)(scale), (int)(hint)) - -#define _mm512_prefetch_i64scatter_pd(addr, index, scale, hint) \ - __builtin_ia32_scatterpfqpd((__mmask8)-1, (__v8di)(__m512i)(index), \ - (void *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_mask_prefetch_i64scatter_pd(addr, mask, index, scale, hint) \ - __builtin_ia32_scatterpfqpd((__mmask8)(mask), (__v8di)(__m512i)(index), \ - (void *)(addr), (int)(scale), \ - (int)(hint)) - -#define _mm512_prefetch_i64scatter_ps(addr, index, scale, hint) \ - __builtin_ia32_scatterpfqps((__mmask8)-1, (__v8di)(__m512i)(index), \ - (void *)(addr), (int)(scale), (int)(hint)) - -#define _mm512_mask_prefetch_i64scatter_ps(addr, mask, index, scale, hint) \ - __builtin_ia32_scatterpfqps((__mmask8)(mask), (__v8di)(__m512i)(index), \ - (void *)(addr), (int)(scale), (int)(hint)) - -#endif diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index 508696d3725b9..cd6cf09b90cad 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -151,10 +151,6 @@ #include #endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512ER__) -#include -#endif - #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512IFMA__) #include #endif @@ -186,10 +182,6 @@ #include #endif -#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512PF__) -#include -#endif - #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512FP16__) #include #endif diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index 7eb6dceaabfae..5ceb986a1f652 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -378,7 +378,7 @@ unsigned int _CountLeadingSigns64(__int64); unsigned int _CountOneBits(unsigned long); unsigned int _CountOneBits64(unsigned __int64); -void __cdecl __prefetch(void *); +void __cdecl __prefetch(const void *); #endif /*----------------------------------------------------------------------------*\ diff --git a/clang/lib/Headers/module.modulemap b/clang/lib/Headers/module.modulemap index 4abfd1d98a635..9ffc249c8d1a2 100644 --- a/clang/lib/Headers/module.modulemap +++ b/clang/lib/Headers/module.modulemap @@ -44,7 +44,6 @@ module _Builtin_intrinsics [system] [extern_c] { textual header "avxintrin.h" textual header "avx2intrin.h" textual header "avx512fintrin.h" - textual header "avx512erintrin.h" textual header "fmaintrin.h" header "x86intrin.h" diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index 8eb88f5a1e94e..a7fa6c5e6898e 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -703,14 +703,16 @@ class IndexingDeclVisitor : public ConstDeclVisitor { IndexCtx.handleDecl(TP); if (const auto *TTP = dyn_cast(TP)) { if (TTP->hasDefaultArgument()) - IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent); + handleTemplateArgumentLoc(TTP->getDefaultArgument(), Parent, + TP->getLexicalDeclContext()); if (auto *C = TTP->getTypeConstraint()) IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(), Parent, TTP->getLexicalDeclContext()); } else if (const auto *NTTP = dyn_cast(TP)) { IndexCtx.indexTypeSourceInfo(NTTP->getTypeSourceInfo(), Parent); if (NTTP->hasDefaultArgument()) - IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent); + handleTemplateArgumentLoc(NTTP->getDefaultArgument(), Parent, + TP->getLexicalDeclContext()); } else if (const auto *TTPD = dyn_cast(TP)) { if (TTPD->hasDefaultArgument()) handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 445d3fd66e387..c528917437332 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -467,6 +467,11 @@ bool Parser::ParseAttributeArgumentList( break; } + if (Actions.DiagnoseUnexpandedParameterPack(Expr.get())) { + SawError = true; + break; + } + Exprs.push_back(Expr.get()); if (Tok.isNot(tok::comma)) @@ -666,6 +671,9 @@ void Parser::ParseGNUAttributeArgs( ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc, Form); return; + } else if (AttrKind == ParsedAttr::AT_CXXAssume) { + ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form); + return; } // These may refer to the function arguments, but need to be parsed early to @@ -720,6 +728,10 @@ unsigned Parser::ParseClangAttributeArgs( ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Form); break; + + case ParsedAttr::AT_CXXAssume: + ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form); + break; } return !Attrs.empty() ? Attrs.begin()->getNumArgs() : 0; } @@ -1923,9 +1935,8 @@ void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs) { // variable. // This function moves attributes that should apply to the type off DS to Attrs. void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, - DeclSpec &DS, - Sema::TagUseKind TUK) { - if (TUK == Sema::TUK_Reference) + DeclSpec &DS, TagUseKind TUK) { + if (TUK == TagUseKind::Reference) return; llvm::SmallVector ToBeMoved; @@ -3306,6 +3317,19 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs, } } +void Parser::DistributeCLateParsedAttrs(Decl *Dcl, + LateParsedAttrList *LateAttrs) { + if (!LateAttrs) + return; + + if (Dcl) { + for (auto *LateAttr : *LateAttrs) { + if (LateAttr->Decls.empty()) + LateAttr->addDecl(Dcl); + } + } +} + /// Bounds attributes (e.g., counted_by): /// AttrName '(' expression ')' void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName, @@ -4843,13 +4867,14 @@ static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, /// void Parser::ParseStructDeclaration( ParsingDeclSpec &DS, - llvm::function_ref FieldsCallback) { + llvm::function_ref FieldsCallback, + LateParsedAttrList *LateFieldAttrs) { if (Tok.is(tok::kw___extension__)) { // __extension__ silences extension warnings in the subexpression. ExtensionRAIIObject O(Diags); // Use RAII to do this. ConsumeToken(); - return ParseStructDeclaration(DS, FieldsCallback); + return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs); } // Parse leading attributes. @@ -4914,10 +4939,12 @@ void Parser::ParseStructDeclaration( } // If attributes exist after the declarator, parse them. - MaybeParseGNUAttributes(DeclaratorInfo.D); + MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs); // We're done with this declarator; invoke the callback. - FieldsCallback(DeclaratorInfo); + Decl *Field = FieldsCallback(DeclaratorInfo); + if (Field) + DistributeCLateParsedAttrs(Field, LateFieldAttrs); // If we don't have a comma, it is either the end of the list (a ';') // or an error, bail out. @@ -4928,6 +4955,73 @@ void Parser::ParseStructDeclaration( } } +// TODO: All callers of this function should be moved to +// `Parser::ParseLexedAttributeList`. +void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs, bool EnterScope, + ParsedAttributes *OutAttrs) { + assert(LAs.parseSoon() && + "Attribute list should be marked for immediate parsing."); + for (auto *LA : LAs) { + ParseLexedCAttribute(*LA, EnterScope, OutAttrs); + delete LA; + } + LAs.clear(); +} + +/// Finish parsing an attribute for which parsing was delayed. +/// This will be called at the end of parsing a class declaration +/// for each LateParsedAttribute. We consume the saved tokens and +/// create an attribute with the arguments filled in. We add this +/// to the Attribute list for the decl. +void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope, + ParsedAttributes *OutAttrs) { + // Create a fake EOF so that attribute parsing won't go off the end of the + // attribute. + Token AttrEnd; + AttrEnd.startToken(); + AttrEnd.setKind(tok::eof); + AttrEnd.setLocation(Tok.getLocation()); + AttrEnd.setEofData(LA.Toks.data()); + LA.Toks.push_back(AttrEnd); + + // Append the current token at the end of the new token stream so that it + // doesn't get lost. + LA.Toks.push_back(Tok); + PP.EnterTokenStream(LA.Toks, /*DisableMacroExpansion=*/true, + /*IsReinject=*/true); + // Drop the current token and bring the first cached one. It's the same token + // as when we entered this function. + ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); + + // TODO: Use `EnterScope` + (void)EnterScope; + + ParsedAttributes Attrs(AttrFactory); + + assert(LA.Decls.size() <= 1 && + "late field attribute expects to have at most one declaration."); + + // Dispatch based on the attribute and parse it + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr, + SourceLocation(), ParsedAttr::Form::GNU(), nullptr); + + for (auto *D : LA.Decls) + Actions.ActOnFinishDelayedAttribute(getCurScope(), D, Attrs); + + // Due to a parsing error, we either went over the cached tokens or + // there are still cached tokens left, so we skip the leftover tokens. + while (Tok.isNot(tok::eof)) + ConsumeAnyToken(); + + // Consume the fake EOF token if it's there + if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) + ConsumeAnyToken(); + + if (OutAttrs) { + OutAttrs->takeAllFrom(Attrs); + } +} + /// ParseStructUnionBody /// struct-contents: /// struct-declaration-list @@ -4951,6 +5045,11 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope); Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); + // `LateAttrParseExperimentalExtOnly=true` requests that only attributes + // marked with `LateAttrParseExperimentalExt` are late parsed. + LateParsedAttrList LateFieldAttrs(/*PSoon=*/true, + /*LateAttrParseExperimentalExtOnly=*/true); + // While we still have something to read, read the declarations in the struct. while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { @@ -5001,18 +5100,19 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, } if (!Tok.is(tok::at)) { - auto CFieldCallback = [&](ParsingFieldDeclarator &FD) { + auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * { // Install the declarator into the current TagDecl. Decl *Field = Actions.ActOnField(getCurScope(), TagDecl, FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D, FD.BitfieldSize); FD.complete(Field); + return Field; }; // Parse all the comma separated declarators. ParsingDeclSpec DS(*this); - ParseStructDeclaration(DS, CFieldCallback); + ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs); } else { // Handle @defs ConsumeToken(); if (!Tok.isObjCAtKeyword(tok::objc_defs)) { @@ -5053,7 +5153,10 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, ParsedAttributes attrs(AttrFactory); // If attributes exist after struct contents, parse them. - MaybeParseGNUAttributes(attrs); + MaybeParseGNUAttributes(attrs, &LateFieldAttrs); + + // Late parse field attributes if necessary. + ParseLexedCAttributeList(LateFieldAttrs, /*EnterScope=*/false); SmallVector FieldDecls(TagDecl->fields()); @@ -5287,9 +5390,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // enum foo {..}; void bar() { enum foo; } <- new foo in bar. // enum foo {..}; void bar() { enum foo x; } <- use of old foo. // - Sema::TagUseKind TUK; + TagUseKind TUK; if (AllowEnumSpecifier == AllowDefiningTypeSpec::No) - TUK = Sema::TUK_Reference; + TUK = TagUseKind::Reference; else if (Tok.is(tok::l_brace)) { if (DS.isFriendSpecified()) { Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) @@ -5301,9 +5404,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, ScopedEnumKWLoc = SourceLocation(); IsScopedUsingClassTag = false; BaseType = TypeResult(); - TUK = Sema::TUK_Friend; + TUK = TagUseKind::Friend; } else { - TUK = Sema::TUK_Definition; + TUK = TagUseKind::Definition; } } else if (!isTypeSpecifier(DSC) && (Tok.is(tok::semi) || @@ -5312,7 +5415,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // An opaque-enum-declaration is required to be standalone (no preceding or // following tokens in the declaration). Sema enforces this separately by // diagnosing anything else in the DeclSpec. - TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; + TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration; if (Tok.isNot(tok::semi)) { // A semicolon was missing after this declaration. Diagnose and recover. ExpectAndConsume(tok::semi, diag::err_expected_after, "enum"); @@ -5320,21 +5423,21 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, Tok.setKind(tok::semi); } } else { - TUK = Sema::TUK_Reference; + TUK = TagUseKind::Reference; } bool IsElaboratedTypeSpecifier = - TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend; + TUK == TagUseKind::Reference || TUK == TagUseKind::Friend; // If this is an elaborated type specifier nested in a larger declaration, // and we delayed diagnostics before, just merge them into the current pool. - if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) { + if (TUK == TagUseKind::Reference && shouldDelayDiagsInTag) { diagsFromTag.redelay(); } MultiTemplateParamsArg TParams; if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && - TUK != Sema::TUK_Reference) { + TUK != TagUseKind::Reference) { if (!getLangOpts().CPlusPlus11 || !SS.isSet()) { // Skip the rest of this declarator, up until the comma or semicolon. Diag(Tok, diag::err_enum_template); @@ -5355,7 +5458,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, SS.setTemplateParamLists(TParams); } - if (!Name && TUK != Sema::TUK_Definition) { + if (!Name && TUK != TagUseKind::Definition) { Diag(Tok, diag::err_enumerator_unnamed_no_def); DS.SetTypeSpecError(); @@ -5388,7 +5491,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, stripTypeAttributesOffDeclSpec(attrs, DS, TUK); SkipBodyInfo SkipBody; - if (!Name && TUK == Sema::TUK_Definition && Tok.is(tok::l_brace) && + if (!Name && TUK == TagUseKind::Definition && Tok.is(tok::l_brace) && NextToken().is(tok::identifier)) SkipBody = Actions.shouldSkipAnonEnumBody(getCurScope(), NextToken().getIdentifierInfo(), @@ -5409,7 +5512,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, OffsetOfState, &SkipBody).get(); if (SkipBody.ShouldSkip) { - assert(TUK == Sema::TUK_Definition && "can only skip a definition"); + assert(TUK == TagUseKind::Definition && "can only skip a definition"); BalancedDelimiterTracker T(*this, tok::l_brace); T.consumeOpen(); @@ -5451,7 +5554,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, if (!TagDecl) { // The action failed to produce an enumeration tag. If this is a // definition, consume the entire definition. - if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) { + if (Tok.is(tok::l_brace) && TUK != TagUseKind::Reference) { ConsumeBrace(); SkipUntil(tok::r_brace, StopAtSemi); } @@ -5460,7 +5563,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, return; } - if (Tok.is(tok::l_brace) && TUK == Sema::TUK_Definition) { + if (Tok.is(tok::l_brace) && TUK == TagUseKind::Definition) { Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl; ParseEnumBody(StartLoc, D); if (SkipBody.CheckSameAsPrevious && diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 5eaec2b621e6f..9a4a777f575b2 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1961,11 +1961,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, MaybeParseCXX11Attributes(Attributes); const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy(); - Sema::TagUseKind TUK; + TagUseKind TUK; if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) == AllowDefiningTypeSpec::No || (getLangOpts().OpenMP && OpenMPDirectiveParsing)) - TUK = Sema::TUK_Reference; + TUK = TagUseKind::Reference; else if (Tok.is(tok::l_brace) || (DSC != DeclSpecContext::DSC_association && getLangOpts().CPlusPlus && Tok.is(tok::colon)) || @@ -1980,10 +1980,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Skip everything up to the semicolon, so that this looks like a proper // friend class (or template thereof) declaration. SkipUntil(tok::semi, StopBeforeMatch); - TUK = Sema::TUK_Friend; + TUK = TagUseKind::Friend; } else { // Okay, this is a class definition. - TUK = Sema::TUK_Definition; + TUK = TagUseKind::Definition; } } else if (isClassCompatibleKeyword() && (NextToken().is(tok::l_square) || @@ -2024,15 +2024,15 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } if (Tok.isOneOf(tok::l_brace, tok::colon)) - TUK = Sema::TUK_Definition; + TUK = TagUseKind::Definition; else - TUK = Sema::TUK_Reference; + TUK = TagUseKind::Reference; PA.Revert(); } else if (!isTypeSpecifier(DSC) && (Tok.is(tok::semi) || (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) { - TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; + TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration; if (Tok.isNot(tok::semi)) { const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy(); // A semicolon was missing after this declaration. Diagnose and recover. @@ -2042,11 +2042,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, Tok.setKind(tok::semi); } } else - TUK = Sema::TUK_Reference; + TUK = TagUseKind::Reference; // Forbid misplaced attributes. In cases of a reference, we pass attributes // to caller to handle. - if (TUK != Sema::TUK_Reference) { + if (TUK != TagUseKind::Reference) { // If this is not a reference, then the only possible // valid place for C++11 attributes to appear here // is between class-key and class-name. If there are @@ -2072,7 +2072,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || - TUK != Sema::TUK_Definition)) { + TUK != TagUseKind::Definition)) { if (DS.getTypeSpecType() != DeclSpec::TST_error) { // We have a declaration or reference to an anonymous class. Diag(StartLoc, diag::err_anon_type_definition) @@ -2082,7 +2082,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // If we are parsing a definition and stop at a base-clause, continue on // until the semicolon. Continuing from the comma will just trick us into // thinking we are seeing a variable declaration. - if (TUK == Sema::TUK_Definition && Tok.is(tok::colon)) + if (TUK == TagUseKind::Definition && Tok.is(tok::colon)) SkipUntil(tok::semi, StopBeforeMatch); else SkipUntil(tok::comma, StopAtSemi); @@ -2103,7 +2103,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, if (TemplateId->isInvalid()) { // Can't build the declaration. } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && - TUK == Sema::TUK_Declaration) { + TUK == TagUseKind::Declaration) { // This is an explicit instantiation of a class template. ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, diag::err_keyword_not_allowed, @@ -2119,8 +2119,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // they have template headers, in which case they're ill-formed // (FIXME: "template friend class A::B;"). // We diagnose this error in ActOnClassTemplateSpecialization. - } else if (TUK == Sema::TUK_Reference || - (TUK == Sema::TUK_Friend && + } else if (TUK == TagUseKind::Reference || + (TUK == TagUseKind::Friend && TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, diag::err_keyword_not_allowed, @@ -2145,10 +2145,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // It this is friend declaration however, since it cannot have a // template header, it is most likely that the user meant to // remove the 'template' keyword. - assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) && + assert((TUK == TagUseKind::Definition || TUK == TagUseKind::Friend) && "Expected a definition here"); - if (TUK == Sema::TUK_Friend) { + if (TUK == TagUseKind::Friend) { Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation); TemplateParams = nullptr; } else { @@ -2179,7 +2179,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, &SkipBody); } } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && - TUK == Sema::TUK_Declaration) { + TUK == TagUseKind::Declaration) { // Explicit instantiation of a member of a class template // specialization, e.g., // @@ -2190,7 +2190,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TagOrTempResult = Actions.ActOnExplicitInstantiation( getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, TagType, StartLoc, SS, Name, NameLoc, attrs); - } else if (TUK == Sema::TUK_Friend && + } else if (TUK == TagUseKind::Friend && TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, diag::err_keyword_not_allowed, @@ -2202,12 +2202,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, TemplateParams ? TemplateParams->size() : 0)); } else { - if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) + if (TUK != TagUseKind::Declaration && TUK != TagUseKind::Definition) ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, diag::err_keyword_not_allowed, /* DiagnoseEmptyAttrs=*/true); - if (TUK == Sema::TUK_Definition && + if (TUK == TagUseKind::Definition && TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { // If the declarator-id is not a template-id, issue a diagnostic and // recover by ignoring the 'template' keyword. @@ -2222,7 +2222,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // reference. For example, we don't need the template parameters here: // template class A *makeA(T t); MultiTemplateParamsArg TParams; - if (TUK != Sema::TUK_Reference && TemplateParams) + if (TUK != TagUseKind::Reference && TemplateParams) TParams = MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size()); @@ -2241,7 +2241,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // If ActOnTag said the type was dependent, try again with the // less common call. if (IsDependent) { - assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); + assert(TUK == TagUseKind::Reference || TUK == TagUseKind::Friend); TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, SS, Name, StartLoc, NameLoc); } @@ -2252,13 +2252,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // just merge them into the current pool. if (shouldDelayDiagsInTag) { diagsFromTag.done(); - if (TUK == Sema::TUK_Reference && + if (TUK == TagUseKind::Reference && TemplateInfo.Kind == ParsedTemplateInfo::Template) diagsFromTag.redelay(); } // If there is a body, parse it and inform the actions module. - if (TUK == Sema::TUK_Definition) { + if (TUK == TagUseKind::Definition) { assert(Tok.is(tok::l_brace) || (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || isClassCompatibleKeyword()); @@ -2316,7 +2316,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // // After a type-specifier, we don't expect a semicolon. This only happens in // C, since definitions are not permitted in this context in C++. - if (TUK == Sema::TUK_Definition && + if (TUK == TagUseKind::Definition && (getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) && (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) { if (Tok.isNot(tok::semi)) { @@ -4560,7 +4560,8 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs, IdentifierInfo *AttrName, SourceLocation AttrNameLoc, - SourceLocation *EndLoc) { + SourceLocation *EndLoc, + ParsedAttr::Form Form) { assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); @@ -4603,7 +4604,7 @@ bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs, auto RParen = Tok.getLocation(); T.consumeClose(); Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), nullptr, - SourceLocation(), &Assumption, 1, ParsedAttr::Form::CXX11()); + SourceLocation(), &Assumption, 1, Form); if (EndLoc) *EndLoc = RParen; @@ -4683,7 +4684,7 @@ bool Parser::ParseCXX11AttributeArgs( ScopeName, ScopeLoc, Form); // So does C++23's assume() attribute. else if (!ScopeName && AttrName->isStr("assume")) { - if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc)) + if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form)) return true; NumArgs = 1; } else diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 89f4acbd25e49..6a2088a73c55b 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -780,16 +780,16 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, } bool addedToDeclSpec = false; - auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) { + auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) -> Decl * { if (FD.D.getIdentifier() == nullptr) { Diag(AtLoc, diag::err_objc_property_requires_field_name) << FD.D.getSourceRange(); - return; + return nullptr; } if (FD.BitfieldSize) { Diag(AtLoc, diag::err_objc_property_bitfield) << FD.D.getSourceRange(); - return; + return nullptr; } // Map a nullability property attribute to a context-sensitive keyword @@ -818,6 +818,7 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, MethodImplKind); FD.complete(Property); + return Property; }; // Parse all the comma separated declarators. @@ -2013,7 +2014,7 @@ void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl, continue; } - auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) { + auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) -> Decl * { assert(getObjCDeclContext() == interfaceDecl && "Ivar should have interfaceDecl as its decl context"); // Install the declarator into the interface decl. @@ -2024,6 +2025,7 @@ void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl, if (Field) AllIvarDecls.push_back(Field); FD.complete(Field); + return Field; }; // Parse all the comma separated declarators. diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 5db3036b00030..e9c60f76165b6 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -920,7 +920,8 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( case OpenACCClauseKind::PresentOrCopyIn: { bool IsReadOnly = tryParseAndConsumeSpecialTokenKind( *this, OpenACCSpecialTokenKind::ReadOnly, ClauseKind); - ParsedClause.setVarListDetails(ParseOpenACCVarList(), IsReadOnly, + ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), + IsReadOnly, /*IsZero=*/false); break; } @@ -932,16 +933,17 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( case OpenACCClauseKind::PresentOrCopyOut: { bool IsZero = tryParseAndConsumeSpecialTokenKind( *this, OpenACCSpecialTokenKind::Zero, ClauseKind); - ParsedClause.setVarListDetails(ParseOpenACCVarList(), + ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), /*IsReadOnly=*/false, IsZero); break; } - case OpenACCClauseKind::Reduction: + case OpenACCClauseKind::Reduction: { // If we're missing a clause-kind (or it is invalid), see if we can parse // the var-list anyway. - ParseReductionOperator(*this); - ParseOpenACCVarList(); + OpenACCReductionOperator Op = ParseReductionOperator(*this); + ParsedClause.setReductionDetails(Op, ParseOpenACCVarList(ClauseKind)); break; + } case OpenACCClauseKind::Self: // The 'self' clause is a var-list instead of a 'condition' in the case of // the 'update' clause, so we have to handle it here. U se an assert to @@ -955,11 +957,11 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( case OpenACCClauseKind::Host: case OpenACCClauseKind::Link: case OpenACCClauseKind::UseDevice: - ParseOpenACCVarList(); + ParseOpenACCVarList(ClauseKind); break; case OpenACCClauseKind::Attach: case OpenACCClauseKind::DevicePtr: - ParsedClause.setVarListDetails(ParseOpenACCVarList(), + ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), /*IsReadOnly=*/false, /*IsZero=*/false); break; case OpenACCClauseKind::Copy: @@ -969,7 +971,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( case OpenACCClauseKind::NoCreate: case OpenACCClauseKind::Present: case OpenACCClauseKind::Private: - ParsedClause.setVarListDetails(ParseOpenACCVarList(), + ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), /*IsReadOnly=*/false, /*IsZero=*/false); break; case OpenACCClauseKind::Collapse: { @@ -1278,7 +1280,7 @@ ExprResult Parser::ParseOpenACCBindClauseArgument() { /// - an array element /// - a member of a composite variable /// - a common block name between slashes (fortran only) -Parser::OpenACCVarParseResult Parser::ParseOpenACCVar() { +Parser::OpenACCVarParseResult Parser::ParseOpenACCVar(OpenACCClauseKind CK) { OpenACCArraySectionRAII ArraySections(*this); ExprResult Res = ParseAssignmentExpression(); @@ -1289,15 +1291,15 @@ Parser::OpenACCVarParseResult Parser::ParseOpenACCVar() { if (!Res.isUsable()) return {Res, OpenACCParseCanContinue::Can}; - Res = getActions().OpenACC().ActOnVar(Res.get()); + Res = getActions().OpenACC().ActOnVar(CK, Res.get()); return {Res, OpenACCParseCanContinue::Can}; } -llvm::SmallVector Parser::ParseOpenACCVarList() { +llvm::SmallVector Parser::ParseOpenACCVarList(OpenACCClauseKind CK) { llvm::SmallVector Vars; - auto [Res, CanContinue] = ParseOpenACCVar(); + auto [Res, CanContinue] = ParseOpenACCVar(CK); if (Res.isUsable()) { Vars.push_back(Res.get()); } else if (CanContinue == OpenACCParseCanContinue::Cannot) { @@ -1308,7 +1310,7 @@ llvm::SmallVector Parser::ParseOpenACCVarList() { while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) { ExpectAndConsume(tok::comma); - auto [Res, CanContinue] = ParseOpenACCVar(); + auto [Res, CanContinue] = ParseOpenACCVar(CK); if (Res.isUsable()) { Vars.push_back(Res.get()); @@ -1342,7 +1344,7 @@ void Parser::ParseOpenACCCacheVarList() { // ParseOpenACCVarList should leave us before a r-paren, so no need to skip // anything here. - ParseOpenACCVarList(); + ParseOpenACCVarList(OpenACCClauseKind::Invalid); } Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() { diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 643fdac287d18..cc6f18b5b319f 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -23,6 +23,7 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaCodeCompletion.h" +#include "clang/Sema/SemaRISCV.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringSwitch.h" #include @@ -4154,7 +4155,7 @@ void PragmaRISCVHandler::HandlePragma(Preprocessor &PP, } if (II->isStr("vector")) - Actions.DeclareRISCVVBuiltins = true; + Actions.RISCV().DeclareRVVBuiltins = true; else if (II->isStr("sifive_vector")) - Actions.DeclareRISCVSiFiveVectorBuiltins = true; + Actions.RISCV().DeclareSiFiveVectorBuiltins = true; } diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index 6b7742cae2db9..fe6471c81ff01 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -71,6 +71,7 @@ add_clang_library(clangSema SemaTemplateInstantiateDecl.cpp SemaTemplateVariadic.cpp SemaType.cpp + SemaX86.cpp TypeLocBuilder.cpp DEPENDS diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index bb283c54b3d29..a2b29a7bdf505 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -308,17 +308,18 @@ struct BuiltinTypeDeclBuilder { return *this; } - TemplateParameterListBuilder addTemplateArgumentList(); - BuiltinTypeDeclBuilder &addSimpleTemplateParams(ArrayRef Names); + TemplateParameterListBuilder addTemplateArgumentList(Sema &S); + BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S, + ArrayRef Names); }; struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &Builder; - ASTContext &AST; + Sema &S; llvm::SmallVector Params; - TemplateParameterListBuilder(BuiltinTypeDeclBuilder &RB) - : Builder(RB), AST(RB.Record->getASTContext()) {} + TemplateParameterListBuilder(Sema &S, BuiltinTypeDeclBuilder &RB) + : Builder(RB), S(S) {} ~TemplateParameterListBuilder() { finalizeTemplateArgs(); } @@ -328,12 +329,15 @@ struct TemplateParameterListBuilder { return *this; unsigned Position = static_cast(Params.size()); auto *Decl = TemplateTypeParmDecl::Create( - AST, Builder.Record->getDeclContext(), SourceLocation(), + S.Context, Builder.Record->getDeclContext(), SourceLocation(), SourceLocation(), /* TemplateDepth */ 0, Position, - &AST.Idents.get(Name, tok::TokenKind::identifier), /* Typename */ false, + &S.Context.Idents.get(Name, tok::TokenKind::identifier), + /* Typename */ false, /* ParameterPack */ false); if (!DefaultValue.isNull()) - Decl->setDefaultArgument(AST.getTrivialTypeSourceInfo(DefaultValue)); + Decl->setDefaultArgument( + S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), + SourceLocation())); Params.emplace_back(Decl); return *this; @@ -342,11 +346,11 @@ struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &finalizeTemplateArgs() { if (Params.empty()) return Builder; - auto *ParamList = - TemplateParameterList::Create(AST, SourceLocation(), SourceLocation(), - Params, SourceLocation(), nullptr); + auto *ParamList = TemplateParameterList::Create(S.Context, SourceLocation(), + SourceLocation(), Params, + SourceLocation(), nullptr); Builder.Template = ClassTemplateDecl::Create( - AST, Builder.Record->getDeclContext(), SourceLocation(), + S.Context, Builder.Record->getDeclContext(), SourceLocation(), DeclarationName(Builder.Record->getIdentifier()), ParamList, Builder.Record); Builder.Record->setDescribedClassTemplate(Builder.Template); @@ -359,20 +363,22 @@ struct TemplateParameterListBuilder { Params.clear(); QualType T = Builder.Template->getInjectedClassNameSpecialization(); - T = AST.getInjectedClassNameType(Builder.Record, T); + T = S.Context.getInjectedClassNameType(Builder.Record, T); return Builder; } }; } // namespace -TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() { - return TemplateParameterListBuilder(*this); +TemplateParameterListBuilder +BuiltinTypeDeclBuilder::addTemplateArgumentList(Sema &S) { + return TemplateParameterListBuilder(S, *this); } BuiltinTypeDeclBuilder & -BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef Names) { - TemplateParameterListBuilder Builder = this->addTemplateArgumentList(); +BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, + ArrayRef Names) { + TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) Builder.addTypeParameter(Name); return Builder.finalizeTemplateArgs(); @@ -426,7 +432,9 @@ void HLSLExternalSemaSource::defineHLSLVectorAlias() { auto *TypeParam = TemplateTypeParmDecl::Create( AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0, &AST.Idents.get("element", tok::TokenKind::identifier), false, false); - TypeParam->setDefaultArgument(AST.getTrivialTypeSourceInfo(AST.FloatTy)); + TypeParam->setDefaultArgument( + AST, SemaPtr->getTrivialTemplateArgumentLoc( + TemplateArgument(AST.FloatTy), QualType(), SourceLocation())); TemplateParams.emplace_back(TypeParam); @@ -434,10 +442,12 @@ void HLSLExternalSemaSource::defineHLSLVectorAlias() { AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 1, &AST.Idents.get("element_count", tok::TokenKind::identifier), AST.IntTy, false, AST.getTrivialTypeSourceInfo(AST.IntTy)); - Expr *LiteralExpr = - IntegerLiteral::Create(AST, llvm::APInt(AST.getIntWidth(AST.IntTy), 4), - AST.IntTy, SourceLocation()); - SizeParam->setDefaultArgument(LiteralExpr); + llvm::APInt Val(AST.getIntWidth(AST.IntTy), 4); + TemplateArgument Default(AST, llvm::APSInt(std::move(Val)), AST.IntTy, + /*IsDefaulted=*/true); + SizeParam->setDefaultArgument( + AST, SemaPtr->getTrivialTemplateArgumentLoc(Default, AST.IntTy, + SourceLocation(), SizeParam)); TemplateParams.emplace_back(SizeParam); auto *ParamList = @@ -492,7 +502,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) + .addSimpleTemplateParams(*SemaPtr, {"element_type"}) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, @@ -503,7 +513,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer") - .addSimpleTemplateParams({"element_type"}) + .addSimpleTemplateParams(*SemaPtr, {"element_type"}) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index f847c49920cf3..d1fb21bb1ae1d 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -49,7 +49,10 @@ #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/SemaOpenMP.h" +#include "clang/Sema/SemaPseudoObject.h" +#include "clang/Sema/SemaRISCV.h" #include "clang/Sema/SemaSYCL.h" +#include "clang/Sema/SemaX86.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TemplateInstCallback.h" #include "clang/Sema/TypoCorrection.h" @@ -210,7 +213,10 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, ObjCPtr(std::make_unique(*this)), OpenACCPtr(std::make_unique(*this)), OpenMPPtr(std::make_unique(*this)), + PseudoObjectPtr(std::make_unique(*this)), + RISCVPtr(std::make_unique(*this)), SYCLPtr(std::make_unique(*this)), + X86Ptr(std::make_unique(*this)), MSPointerToMemberRepresentationMethod( LangOpts.getMSPointerToMemberRepresentationMethod()), MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()), @@ -2049,7 +2055,7 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { if (TI.hasRISCVVTypes() && Ty->isRVVSizelessBuiltinType() && FD) { llvm::StringMap CallerFeatureMap; Context.getFunctionFeatureMap(CallerFeatureMap, FD); - checkRVVTypeSupport(Ty, Loc, D, CallerFeatureMap); + RISCV().checkRVVTypeSupport(Ty, Loc, D, CallerFeatureMap); } // Don't allow SVE types in functions without a SVE target. diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index 663b6f35b869d..22f5a2f663477 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -987,11 +987,6 @@ void Sema::DiagnoseUnguardedAvailabilityViolations(Decl *D) { Stmt *Body = nullptr; if (auto *FD = D->getAsFunction()) { - // FIXME: We only examine the pattern decl for availability violations now, - // but we should also examine instantiated templates. - if (FD->isTemplateInstantiation()) - return; - Body = FD->getBody(); if (auto *CD = dyn_cast(FD)) diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 483ec7e36eaed..7db6b1dfe923b 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -25,6 +25,7 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" +#include "clang/Sema/SemaRISCV.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include @@ -2391,7 +2392,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, } // Allow bitcasting between SVE VLATs and VLSTs, and vice-versa. - if (Self.isValidRVVBitcast(SrcType, DestType)) { + if (Self.RISCV().isValidRVVBitcast(SrcType, DestType)) { Kind = CK_BitCast; return TC_Success; } @@ -3002,7 +3003,7 @@ void CastOperation::CheckCStyleCast() { // Allow bitcasting between compatible RVV vector types. if ((SrcType->isVectorType() || DestType->isVectorType()) && - Self.isValidRVVBitcast(SrcType, DestType)) { + Self.RISCV().isValidRVVBitcast(SrcType, DestType)) { Kind = CK_BitCast; return; } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f2dc8e9dd0050..c3251f3cc9d81 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -63,6 +63,8 @@ #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" +#include "clang/Sema/SemaRISCV.h" +#include "clang/Sema/SemaX86.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" @@ -120,13 +122,12 @@ static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, /// Checks that a call expression's argument count is at least the desired /// number. This is useful when doing custom type-checking on a variadic /// function. Returns true on error. -static bool checkArgCountAtLeast(Sema &S, CallExpr *Call, - unsigned MinArgCount) { +bool Sema::checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount) { unsigned ArgCount = Call->getNumArgs(); if (ArgCount >= MinArgCount) return false; - return S.Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args) + return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args) << 0 /*function call*/ << MinArgCount << ArgCount << /*is non object*/ 0 << Call->getSourceRange(); } @@ -134,12 +135,11 @@ static bool checkArgCountAtLeast(Sema &S, CallExpr *Call, /// Checks that a call expression's argument count is at most the desired /// number. This is useful when doing custom type-checking on a variadic /// function. Returns true on error. -static bool checkArgCountAtMost(Sema &S, CallExpr *Call, unsigned MaxArgCount) { +bool Sema::checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount) { unsigned ArgCount = Call->getNumArgs(); if (ArgCount <= MaxArgCount) return false; - return S.Diag(Call->getEndLoc(), - diag::err_typecheck_call_too_many_args_at_most) + return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most) << 0 /*function call*/ << MaxArgCount << ArgCount << /*is non object*/ 0 << Call->getSourceRange(); } @@ -147,20 +147,20 @@ static bool checkArgCountAtMost(Sema &S, CallExpr *Call, unsigned MaxArgCount) { /// Checks that a call expression's argument count is in the desired range. This /// is useful when doing custom type-checking on a variadic function. Returns /// true on error. -static bool checkArgCountRange(Sema &S, CallExpr *Call, unsigned MinArgCount, - unsigned MaxArgCount) { - return checkArgCountAtLeast(S, Call, MinArgCount) || - checkArgCountAtMost(S, Call, MaxArgCount); +bool Sema::checkArgCountRange(CallExpr *Call, unsigned MinArgCount, + unsigned MaxArgCount) { + return checkArgCountAtLeast(Call, MinArgCount) || + checkArgCountAtMost(Call, MaxArgCount); } /// Checks that a call expression's argument count is the desired number. /// This is useful when doing custom type-checking. Returns true on error. -static bool checkArgCount(Sema &S, CallExpr *Call, unsigned DesiredArgCount) { +bool Sema::checkArgCount(CallExpr *Call, unsigned DesiredArgCount) { unsigned ArgCount = Call->getNumArgs(); if (ArgCount == DesiredArgCount) return false; - if (checkArgCountAtLeast(S, Call, DesiredArgCount)) + if (checkArgCountAtLeast(Call, DesiredArgCount)) return true; assert(ArgCount > DesiredArgCount && "should have diagnosed this"); @@ -168,7 +168,7 @@ static bool checkArgCount(Sema &S, CallExpr *Call, unsigned DesiredArgCount) { SourceRange Range(Call->getArg(DesiredArgCount)->getBeginLoc(), Call->getArg(ArgCount - 1)->getEndLoc()); - return S.Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) + return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << DesiredArgCount << ArgCount << /*is non object*/ 0 << Call->getArg(1)->getSourceRange(); } @@ -190,7 +190,7 @@ static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty) { /// Check that the first argument to __builtin_annotation is an integer /// and the second argument is a non-wide string literal. static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 2)) + if (S.checkArgCount(TheCall, 2)) return true; // First argument should be an integer. @@ -240,7 +240,7 @@ static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall) { /// Check that the argument to __builtin_addressof is a glvalue, and set the /// result type to the corresponding pointer type. static bool BuiltinAddressof(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 1)) + if (S.checkArgCount(TheCall, 1)) return true; ExprResult Arg(TheCall->getArg(0)); @@ -255,7 +255,7 @@ static bool BuiltinAddressof(Sema &S, CallExpr *TheCall) { /// Check that the argument to __builtin_function_start is a function. static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 1)) + if (S.checkArgCount(TheCall, 1)) return true; ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); @@ -279,7 +279,7 @@ static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall) { /// Check the number of arguments and set the result type to /// the argument type. static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 1)) + if (S.checkArgCount(TheCall, 1)) return true; TheCall->setType(TheCall->getArg(0)->getType()); @@ -290,7 +290,7 @@ static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall) { /// __builtin_aligned_{up,down}(value, alignment) is an integer or a pointer /// type (but not a function pointer) and that the alignment is a power-of-two. static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) { - if (checkArgCount(S, TheCall, 2)) + if (S.checkArgCount(TheCall, 2)) return true; clang::Expr *Source = TheCall->getArg(0); @@ -368,7 +368,7 @@ static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) { } static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID) { - if (checkArgCount(S, TheCall, 3)) + if (S.checkArgCount(TheCall, 3)) return true; std::pair Builtins[] = { @@ -696,7 +696,7 @@ struct BuiltinDumpStructGenerator { } // namespace static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall) { - if (checkArgCountAtLeast(S, TheCall, 2)) + if (S.checkArgCountAtLeast(TheCall, 2)) return ExprError(); ExprResult PtrArgResult = S.DefaultLvalueConversion(TheCall->getArg(0)); @@ -762,7 +762,7 @@ static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall) { } static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) { - if (checkArgCount(S, BuiltinCall, 2)) + if (S.checkArgCount(BuiltinCall, 2)) return true; SourceLocation BuiltinLoc = BuiltinCall->getBeginLoc(); @@ -1504,7 +1504,7 @@ static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) { } static bool OpenCLBuiltinNDRangeAndBlock(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 2)) + if (S.checkArgCount(TheCall, 2)) return true; if (checkOpenCLSubgroupExt(S, TheCall)) @@ -1531,7 +1531,7 @@ static bool OpenCLBuiltinNDRangeAndBlock(Sema &S, CallExpr *TheCall) { /// get_kernel_work_group_size /// and get_kernel_preferred_work_group_size_multiple builtin functions. static bool OpenCLBuiltinKernelWorkGroupSize(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 1)) + if (S.checkArgCount(TheCall, 1)) return true; Expr *BlockArg = TheCall->getArg(0); @@ -1861,7 +1861,7 @@ static bool BuiltinRWPipe(Sema &S, CallExpr *Call) { // \param Call The call to the builtin function to be analyzed. // \return True if a semantic error was found, false otherwise. static bool BuiltinReserveRWPipe(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 2)) + if (S.checkArgCount(Call, 2)) return true; if (checkOpenCLPipeArg(S, Call)) @@ -1890,7 +1890,7 @@ static bool BuiltinReserveRWPipe(Sema &S, CallExpr *Call) { // \param Call The call to the builtin function to be analyzed. // \return True if a semantic error was found, false otherwise. static bool BuiltinCommitRWPipe(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 2)) + if (S.checkArgCount(Call, 2)) return true; if (checkOpenCLPipeArg(S, Call)) @@ -1913,7 +1913,7 @@ static bool BuiltinCommitRWPipe(Sema &S, CallExpr *Call) { // \param Call The call to the builtin function to be analyzed. // \return True if a semantic error was found, false otherwise. static bool BuiltinPipePackets(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 1)) + if (S.checkArgCount(Call, 1)) return true; if (!Call->getArg(0)->getType()->isPipeType()) { @@ -1932,7 +1932,7 @@ static bool BuiltinPipePackets(Sema &S, CallExpr *Call) { // \param Call A pointer to the builtin call. // \return True if a semantic error has been found, false otherwise. static bool OpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID, CallExpr *Call) { - if (checkArgCount(S, Call, 1)) + if (S.checkArgCount(Call, 1)) return true; auto RT = Call->getArg(0)->getType(); @@ -2087,7 +2087,7 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg, } static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 2)) + if (S.checkArgCount(Call, 2)) return ExprError(); if (checkPointerAuthEnabled(S, Call)) return ExprError(); @@ -2100,7 +2100,7 @@ static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call) { } static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 2)) + if (S.checkArgCount(Call, 2)) return ExprError(); if (checkPointerAuthEnabled(S, Call)) return ExprError(); @@ -2113,7 +2113,7 @@ static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call) { } static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 2)) + if (S.checkArgCount(Call, 2)) return ExprError(); if (checkPointerAuthEnabled(S, Call)) return ExprError(); @@ -2127,7 +2127,7 @@ static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call) { static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind) { - if (checkArgCount(S, Call, 3)) + if (S.checkArgCount(Call, 3)) return ExprError(); if (checkPointerAuthEnabled(S, Call)) return ExprError(); @@ -2141,7 +2141,7 @@ static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, } static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) { - if (checkArgCount(S, Call, 5)) + if (S.checkArgCount(Call, 5)) return ExprError(); if (checkPointerAuthEnabled(S, Call)) return ExprError(); @@ -2157,7 +2157,7 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) { } static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 1)) + if (S.checkArgCount(TheCall, 1)) return ExprError(); // Compute __builtin_launder's parameter type from the argument. @@ -2278,7 +2278,7 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, return CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall); case llvm::Triple::x86: case llvm::Triple::x86_64: - return CheckX86BuiltinFunctionCall(TI, BuiltinID, TheCall); + return X86().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::ppc: case llvm::Triple::ppcle: case llvm::Triple::ppc64: @@ -2288,7 +2288,7 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, return CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall); case llvm::Triple::riscv32: case llvm::Triple::riscv64: - return CheckRISCVBuiltinFunctionCall(TI, BuiltinID, TheCall); + return RISCV().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall); case llvm::Triple::loongarch32: case llvm::Triple::loongarch64: return CheckLoongArchBuiltinFunctionCall(TI, BuiltinID, TheCall); @@ -2377,7 +2377,7 @@ static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, /// Checks that __builtin_popcountg was called with a single argument, which is /// an unsigned integer. static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) { - if (checkArgCount(S, TheCall, 1)) + if (S.checkArgCount(TheCall, 1)) return true; ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0)); @@ -2401,7 +2401,7 @@ static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) { /// an unsigned integer, and an optional second argument, which is promoted to /// an 'int'. static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) { - if (checkArgCountRange(S, TheCall, 1, 2)) + if (S.checkArgCountRange(TheCall, 1, 2)) return true; ExprResult Arg0Res = S.DefaultLvalueConversion(TheCall->getArg(0)); @@ -2625,7 +2625,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); break; case Builtin::BI__builtin_classify_type: - if (checkArgCount(*this, TheCall, 1)) return true; + if (checkArgCount(TheCall, 1)) + return true; TheCall->setType(Context.IntTy); break; case Builtin::BI__builtin_complex: @@ -2633,7 +2634,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); break; case Builtin::BI__builtin_constant_p: { - if (checkArgCount(*this, TheCall, 1)) return true; + if (checkArgCount(TheCall, 1)) + return true; ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); if (Arg.isInvalid()) return true; TheCall->setArg(0, Arg.get()); @@ -2822,7 +2824,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return BuiltinDumpStruct(*this, TheCall); case Builtin::BI__builtin_expect_with_probability: { // We first want to ensure we are called with 3 arguments - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return ExprError(); // then check probability is constant float in range [0.0, 1.0] const Expr *ProbArg = TheCall->getArg(2); @@ -2870,7 +2872,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); break; case Builtin::BI__GetExceptionInfo: - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return ExprError(); if (CheckCXXThrowOperand( @@ -2891,7 +2893,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, // These are all expected to be of the form // T &/&&/* f(U &/&&) // where T and U only differ in qualification. - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return ExprError(); QualType Param = FDecl->getParamDecl(0)->getType(); QualType Result = FDecl->getReturnType(); @@ -3129,7 +3131,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, } case Builtin::BI__builtin_elementwise_copysign: { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return ExprError(); ExprResult Magnitude = UsualUnaryConversions(TheCall->getArg(0)); @@ -3806,7 +3808,7 @@ bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, DeclRefExpr *DRE =cast(TheCall->getCallee()->IgnoreParenCasts()); // Ensure that we have the proper number of arguments. - if (checkArgCount(*this, TheCall, IsLdrex ? 1 : 2)) + if (checkArgCount(TheCall, IsLdrex ? 1 : 2)) return true; // Inspect the pointer argument of the atomic builtin. This should always be @@ -3822,7 +3824,7 @@ bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, const PointerType *pointerType = PointerArg->getType()->getAs(); if (!pointerType) { Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) - << PointerArg->getType() << PointerArg->getSourceRange(); + << PointerArg->getType() << 0 << PointerArg->getSourceRange(); return true; } @@ -3856,7 +3858,7 @@ bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && !ValType->isBlockPointerType() && !ValType->isFloatingType()) { Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr) - << PointerArg->getType() << PointerArg->getSourceRange(); + << PointerArg->getType() << 0 << PointerArg->getSourceRange(); return true; } @@ -4145,7 +4147,7 @@ bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, BuiltinID == BPF::BI__builtin_preserve_enum_value) && "unexpected BPF builtin"); - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; // The second argument needs to be a constant int @@ -5589,12 +5591,12 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { switch (BuiltinID) { case Builtin::BI__builtin_hlsl_elementwise_all: case Builtin::BI__builtin_hlsl_elementwise_any: { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; break; } case Builtin::BI__builtin_hlsl_elementwise_clamp: { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return true; if (CheckVectorElementCallArgs(this, TheCall)) return true; @@ -5605,7 +5607,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { break; } case Builtin::BI__builtin_hlsl_dot: { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; if (CheckVectorElementCallArgs(this, TheCall)) return true; @@ -5639,7 +5641,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { break; } case Builtin::BI__builtin_hlsl_lerp: { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return true; if (CheckVectorElementCallArgs(this, TheCall)) return true; @@ -5650,7 +5652,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { break; } case Builtin::BI__builtin_hlsl_mad: { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return true; if (CheckVectorElementCallArgs(this, TheCall)) return true; @@ -5694,6 +5696,28 @@ bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, // position of memory order and scope arguments in the builtin unsigned OrderIndex, ScopeIndex; switch (BuiltinID) { + case AMDGPU::BI__builtin_amdgcn_global_load_lds: { + constexpr const int SizeIdx = 2; + llvm::APSInt Size; + Expr *ArgExpr = TheCall->getArg(SizeIdx); + ExprResult R = VerifyIntegerConstantExpression(ArgExpr, &Size); + if (R.isInvalid()) + return true; + switch (Size.getSExtValue()) { + case 1: + case 2: + case 4: + return false; + default: + Diag(ArgExpr->getExprLoc(), + diag::err_amdgcn_global_load_lds_size_invalid_value) + << ArgExpr->getSourceRange(); + Diag(ArgExpr->getExprLoc(), + diag::note_amdgcn_global_load_lds_size_valid_value) + << ArgExpr->getSourceRange(); + return true; + } + } case AMDGPU::BI__builtin_amdgcn_get_fpenv: case AMDGPU::BI__builtin_amdgcn_set_fpenv: return false; @@ -5753,866 +5777,6 @@ bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, return false; } -bool Sema::CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum) { - llvm::APSInt Result; - - // We can't check the value of a dependent argument. - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - return false; - - // Check constant-ness first. - if (BuiltinConstantArg(TheCall, ArgNum, Result)) - return true; - - int64_t Val = Result.getSExtValue(); - if ((Val >= 0 && Val <= 3) || (Val >= 5 && Val <= 7)) - return false; - - return Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_invalid_lmul) - << Arg->getSourceRange(); -} - -static bool CheckInvalidVLENandLMUL(const TargetInfo &TI, CallExpr *TheCall, - Sema &S, QualType Type, int EGW) { - assert((EGW == 128 || EGW == 256) && "EGW can only be 128 or 256 bits"); - - // LMUL * VLEN >= EGW - ASTContext::BuiltinVectorTypeInfo Info = - S.Context.getBuiltinVectorTypeInfo(Type->castAs()); - unsigned ElemSize = S.Context.getTypeSize(Info.ElementType); - unsigned MinElemCount = Info.EC.getKnownMinValue(); - - unsigned EGS = EGW / ElemSize; - // If EGS is less than or equal to the minimum number of elements, then the - // type is valid. - if (EGS <= MinElemCount) - return false; - - // Otherwise, we need vscale to be at least EGS / MinElemCont. - assert(EGS % MinElemCount == 0); - unsigned VScaleFactor = EGS / MinElemCount; - // Vscale is VLEN/RVVBitsPerBlock. - unsigned MinRequiredVLEN = VScaleFactor * llvm::RISCV::RVVBitsPerBlock; - std::string RequiredExt = "zvl" + std::to_string(MinRequiredVLEN) + "b"; - if (!TI.hasFeature(RequiredExt)) - return S.Diag(TheCall->getBeginLoc(), - diag::err_riscv_type_requires_extension) << Type << RequiredExt; - - return false; -} - -bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, - unsigned BuiltinID, - CallExpr *TheCall) { - // vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx, - // vsmul.vv, vsmul.vx are not included for EEW=64 in Zve64*. - switch (BuiltinID) { - default: - break; - case RISCVVector::BI__builtin_rvv_vmulhsu_vv: - case RISCVVector::BI__builtin_rvv_vmulhsu_vx: - case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tu: - case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tu: - case RISCVVector::BI__builtin_rvv_vmulhsu_vv_m: - case RISCVVector::BI__builtin_rvv_vmulhsu_vx_m: - case RISCVVector::BI__builtin_rvv_vmulhsu_vv_mu: - case RISCVVector::BI__builtin_rvv_vmulhsu_vx_mu: - case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tum: - case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tum: - case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tumu: - case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tumu: - case RISCVVector::BI__builtin_rvv_vmulhu_vv: - case RISCVVector::BI__builtin_rvv_vmulhu_vx: - case RISCVVector::BI__builtin_rvv_vmulhu_vv_tu: - case RISCVVector::BI__builtin_rvv_vmulhu_vx_tu: - case RISCVVector::BI__builtin_rvv_vmulhu_vv_m: - case RISCVVector::BI__builtin_rvv_vmulhu_vx_m: - case RISCVVector::BI__builtin_rvv_vmulhu_vv_mu: - case RISCVVector::BI__builtin_rvv_vmulhu_vx_mu: - case RISCVVector::BI__builtin_rvv_vmulhu_vv_tum: - case RISCVVector::BI__builtin_rvv_vmulhu_vx_tum: - case RISCVVector::BI__builtin_rvv_vmulhu_vv_tumu: - case RISCVVector::BI__builtin_rvv_vmulhu_vx_tumu: - case RISCVVector::BI__builtin_rvv_vmulh_vv: - case RISCVVector::BI__builtin_rvv_vmulh_vx: - case RISCVVector::BI__builtin_rvv_vmulh_vv_tu: - case RISCVVector::BI__builtin_rvv_vmulh_vx_tu: - case RISCVVector::BI__builtin_rvv_vmulh_vv_m: - case RISCVVector::BI__builtin_rvv_vmulh_vx_m: - case RISCVVector::BI__builtin_rvv_vmulh_vv_mu: - case RISCVVector::BI__builtin_rvv_vmulh_vx_mu: - case RISCVVector::BI__builtin_rvv_vmulh_vv_tum: - case RISCVVector::BI__builtin_rvv_vmulh_vx_tum: - case RISCVVector::BI__builtin_rvv_vmulh_vv_tumu: - case RISCVVector::BI__builtin_rvv_vmulh_vx_tumu: - case RISCVVector::BI__builtin_rvv_vsmul_vv: - case RISCVVector::BI__builtin_rvv_vsmul_vx: - case RISCVVector::BI__builtin_rvv_vsmul_vv_tu: - case RISCVVector::BI__builtin_rvv_vsmul_vx_tu: - case RISCVVector::BI__builtin_rvv_vsmul_vv_m: - case RISCVVector::BI__builtin_rvv_vsmul_vx_m: - case RISCVVector::BI__builtin_rvv_vsmul_vv_mu: - case RISCVVector::BI__builtin_rvv_vsmul_vx_mu: - case RISCVVector::BI__builtin_rvv_vsmul_vv_tum: - case RISCVVector::BI__builtin_rvv_vsmul_vx_tum: - case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu: - case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu: { - ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo( - TheCall->getType()->castAs()); - - if (Context.getTypeSize(Info.ElementType) == 64 && !TI.hasFeature("v")) - return Diag(TheCall->getBeginLoc(), - diag::err_riscv_builtin_requires_extension) - << /* IsExtension */ true << TheCall->getSourceRange() << "v"; - - break; - } - } - - switch (BuiltinID) { - case RISCVVector::BI__builtin_rvv_vsetvli: - return BuiltinConstantArgRange(TheCall, 1, 0, 3) || - CheckRISCVLMUL(TheCall, 2); - case RISCVVector::BI__builtin_rvv_vsetvlimax: - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - CheckRISCVLMUL(TheCall, 1); - case RISCVVector::BI__builtin_rvv_vget_v: { - ASTContext::BuiltinVectorTypeInfo ResVecInfo = - Context.getBuiltinVectorTypeInfo(cast( - TheCall->getType().getCanonicalType().getTypePtr())); - ASTContext::BuiltinVectorTypeInfo VecInfo = - Context.getBuiltinVectorTypeInfo(cast( - TheCall->getArg(0)->getType().getCanonicalType().getTypePtr())); - unsigned MaxIndex; - if (VecInfo.NumVectors != 1) // vget for tuple type - MaxIndex = VecInfo.NumVectors; - else // vget for non-tuple type - MaxIndex = (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors) / - (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors); - return BuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); - } - case RISCVVector::BI__builtin_rvv_vset_v: { - ASTContext::BuiltinVectorTypeInfo ResVecInfo = - Context.getBuiltinVectorTypeInfo(cast( - TheCall->getType().getCanonicalType().getTypePtr())); - ASTContext::BuiltinVectorTypeInfo VecInfo = - Context.getBuiltinVectorTypeInfo(cast( - TheCall->getArg(2)->getType().getCanonicalType().getTypePtr())); - unsigned MaxIndex; - if (ResVecInfo.NumVectors != 1) // vset for tuple type - MaxIndex = ResVecInfo.NumVectors; - else // vset fo non-tuple type - MaxIndex = (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors) / - (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors); - return BuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); - } - // Vector Crypto - case RISCVVector::BI__builtin_rvv_vaeskf1_vi_tu: - case RISCVVector::BI__builtin_rvv_vaeskf2_vi_tu: - case RISCVVector::BI__builtin_rvv_vaeskf2_vi: - case RISCVVector::BI__builtin_rvv_vsm4k_vi_tu: { - QualType Op1Type = TheCall->getArg(0)->getType(); - QualType Op2Type = TheCall->getArg(1)->getType(); - return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, 128) || - CheckInvalidVLENandLMUL(TI, TheCall, *this, Op2Type, 128) || - BuiltinConstantArgRange(TheCall, 2, 0, 31); - } - case RISCVVector::BI__builtin_rvv_vsm3c_vi_tu: - case RISCVVector::BI__builtin_rvv_vsm3c_vi: { - QualType Op1Type = TheCall->getArg(0)->getType(); - return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, 256) || - BuiltinConstantArgRange(TheCall, 2, 0, 31); - } - case RISCVVector::BI__builtin_rvv_vaeskf1_vi: - case RISCVVector::BI__builtin_rvv_vsm4k_vi: { - QualType Op1Type = TheCall->getArg(0)->getType(); - return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, 128) || - BuiltinConstantArgRange(TheCall, 1, 0, 31); - } - case RISCVVector::BI__builtin_rvv_vaesdf_vv: - case RISCVVector::BI__builtin_rvv_vaesdf_vs: - case RISCVVector::BI__builtin_rvv_vaesdm_vv: - case RISCVVector::BI__builtin_rvv_vaesdm_vs: - case RISCVVector::BI__builtin_rvv_vaesef_vv: - case RISCVVector::BI__builtin_rvv_vaesef_vs: - case RISCVVector::BI__builtin_rvv_vaesem_vv: - case RISCVVector::BI__builtin_rvv_vaesem_vs: - case RISCVVector::BI__builtin_rvv_vaesz_vs: - case RISCVVector::BI__builtin_rvv_vsm4r_vv: - case RISCVVector::BI__builtin_rvv_vsm4r_vs: - case RISCVVector::BI__builtin_rvv_vaesdf_vv_tu: - case RISCVVector::BI__builtin_rvv_vaesdf_vs_tu: - case RISCVVector::BI__builtin_rvv_vaesdm_vv_tu: - case RISCVVector::BI__builtin_rvv_vaesdm_vs_tu: - case RISCVVector::BI__builtin_rvv_vaesef_vv_tu: - case RISCVVector::BI__builtin_rvv_vaesef_vs_tu: - case RISCVVector::BI__builtin_rvv_vaesem_vv_tu: - case RISCVVector::BI__builtin_rvv_vaesem_vs_tu: - case RISCVVector::BI__builtin_rvv_vaesz_vs_tu: - case RISCVVector::BI__builtin_rvv_vsm4r_vv_tu: - case RISCVVector::BI__builtin_rvv_vsm4r_vs_tu: { - QualType Op1Type = TheCall->getArg(0)->getType(); - QualType Op2Type = TheCall->getArg(1)->getType(); - return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, 128) || - CheckInvalidVLENandLMUL(TI, TheCall, *this, Op2Type, 128); - } - case RISCVVector::BI__builtin_rvv_vsha2ch_vv: - case RISCVVector::BI__builtin_rvv_vsha2cl_vv: - case RISCVVector::BI__builtin_rvv_vsha2ms_vv: - case RISCVVector::BI__builtin_rvv_vsha2ch_vv_tu: - case RISCVVector::BI__builtin_rvv_vsha2cl_vv_tu: - case RISCVVector::BI__builtin_rvv_vsha2ms_vv_tu: { - QualType Op1Type = TheCall->getArg(0)->getType(); - QualType Op2Type = TheCall->getArg(1)->getType(); - QualType Op3Type = TheCall->getArg(2)->getType(); - ASTContext::BuiltinVectorTypeInfo Info = - Context.getBuiltinVectorTypeInfo(Op1Type->castAs()); - uint64_t ElemSize = Context.getTypeSize(Info.ElementType); - if (ElemSize == 64 && !TI.hasFeature("zvknhb")) - return Diag(TheCall->getBeginLoc(), - diag::err_riscv_builtin_requires_extension) - << /* IsExtension */ true << TheCall->getSourceRange() << "zvknb"; - - return CheckInvalidVLENandLMUL(TI, TheCall, *this, Op1Type, ElemSize * 4) || - CheckInvalidVLENandLMUL(TI, TheCall, *this, Op2Type, ElemSize * 4) || - CheckInvalidVLENandLMUL(TI, TheCall, *this, Op3Type, ElemSize * 4); - } - - case RISCVVector::BI__builtin_rvv_sf_vc_i_se: - // bit_27_26, bit_24_20, bit_11_7, simm5, sew, log2lmul - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 1, 0, 31) || - BuiltinConstantArgRange(TheCall, 2, 0, 31) || - BuiltinConstantArgRange(TheCall, 3, -16, 15) || - CheckRISCVLMUL(TheCall, 5); - case RISCVVector::BI__builtin_rvv_sf_vc_iv_se: - // bit_27_26, bit_11_7, vs2, simm5 - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 1, 0, 31) || - BuiltinConstantArgRange(TheCall, 3, -16, 15); - case RISCVVector::BI__builtin_rvv_sf_vc_v_i: - case RISCVVector::BI__builtin_rvv_sf_vc_v_i_se: - // bit_27_26, bit_24_20, simm5 - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 1, 0, 31) || - BuiltinConstantArgRange(TheCall, 2, -16, 15); - case RISCVVector::BI__builtin_rvv_sf_vc_v_iv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_iv_se: - // bit_27_26, vs2, simm5 - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 2, -16, 15); - case RISCVVector::BI__builtin_rvv_sf_vc_ivv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_ivw_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_ivv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_ivw: - case RISCVVector::BI__builtin_rvv_sf_vc_v_ivv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_ivw_se: - // bit_27_26, vd, vs2, simm5 - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 3, -16, 15); - case RISCVVector::BI__builtin_rvv_sf_vc_x_se: - // bit_27_26, bit_24_20, bit_11_7, xs1, sew, log2lmul - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 1, 0, 31) || - BuiltinConstantArgRange(TheCall, 2, 0, 31) || - CheckRISCVLMUL(TheCall, 5); - case RISCVVector::BI__builtin_rvv_sf_vc_xv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_vv_se: - // bit_27_26, bit_11_7, vs2, xs1/vs1 - case RISCVVector::BI__builtin_rvv_sf_vc_v_x: - case RISCVVector::BI__builtin_rvv_sf_vc_v_x_se: - // bit_27_26, bit_24-20, xs1 - return BuiltinConstantArgRange(TheCall, 0, 0, 3) || - BuiltinConstantArgRange(TheCall, 1, 0, 31); - case RISCVVector::BI__builtin_rvv_sf_vc_vvv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_xvv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_vvw_se: - case RISCVVector::BI__builtin_rvv_sf_vc_xvw_se: - // bit_27_26, vd, vs2, xs1 - case RISCVVector::BI__builtin_rvv_sf_vc_v_xv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_vv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_xv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_vv_se: - // bit_27_26, vs2, xs1/vs1 - case RISCVVector::BI__builtin_rvv_sf_vc_v_xvv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_vvv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_xvw: - case RISCVVector::BI__builtin_rvv_sf_vc_v_vvw: - case RISCVVector::BI__builtin_rvv_sf_vc_v_xvv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_vvv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_xvw_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_vvw_se: - // bit_27_26, vd, vs2, xs1/vs1 - return BuiltinConstantArgRange(TheCall, 0, 0, 3); - case RISCVVector::BI__builtin_rvv_sf_vc_fv_se: - // bit_26, bit_11_7, vs2, fs1 - return BuiltinConstantArgRange(TheCall, 0, 0, 1) || - BuiltinConstantArgRange(TheCall, 1, 0, 31); - case RISCVVector::BI__builtin_rvv_sf_vc_fvv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_fvw_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_fvv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_fvw: - case RISCVVector::BI__builtin_rvv_sf_vc_v_fvv_se: - case RISCVVector::BI__builtin_rvv_sf_vc_v_fvw_se: - // bit_26, vd, vs2, fs1 - case RISCVVector::BI__builtin_rvv_sf_vc_v_fv: - case RISCVVector::BI__builtin_rvv_sf_vc_v_fv_se: - // bit_26, vs2, fs1 - return BuiltinConstantArgRange(TheCall, 0, 0, 1); - // Check if byteselect is in [0, 3] - case RISCV::BI__builtin_riscv_aes32dsi: - case RISCV::BI__builtin_riscv_aes32dsmi: - case RISCV::BI__builtin_riscv_aes32esi: - case RISCV::BI__builtin_riscv_aes32esmi: - case RISCV::BI__builtin_riscv_sm4ks: - case RISCV::BI__builtin_riscv_sm4ed: - return BuiltinConstantArgRange(TheCall, 2, 0, 3); - // Check if rnum is in [0, 10] - case RISCV::BI__builtin_riscv_aes64ks1i: - return BuiltinConstantArgRange(TheCall, 1, 0, 10); - // Check if value range for vxrm is in [0, 3] - case RISCVVector::BI__builtin_rvv_vaaddu_vv: - case RISCVVector::BI__builtin_rvv_vaaddu_vx: - case RISCVVector::BI__builtin_rvv_vaadd_vv: - case RISCVVector::BI__builtin_rvv_vaadd_vx: - case RISCVVector::BI__builtin_rvv_vasubu_vv: - case RISCVVector::BI__builtin_rvv_vasubu_vx: - case RISCVVector::BI__builtin_rvv_vasub_vv: - case RISCVVector::BI__builtin_rvv_vasub_vx: - case RISCVVector::BI__builtin_rvv_vsmul_vv: - case RISCVVector::BI__builtin_rvv_vsmul_vx: - case RISCVVector::BI__builtin_rvv_vssra_vv: - case RISCVVector::BI__builtin_rvv_vssra_vx: - case RISCVVector::BI__builtin_rvv_vssrl_vv: - case RISCVVector::BI__builtin_rvv_vssrl_vx: - case RISCVVector::BI__builtin_rvv_vnclip_wv: - case RISCVVector::BI__builtin_rvv_vnclip_wx: - case RISCVVector::BI__builtin_rvv_vnclipu_wv: - case RISCVVector::BI__builtin_rvv_vnclipu_wx: - return BuiltinConstantArgRange(TheCall, 2, 0, 3); - case RISCVVector::BI__builtin_rvv_vaaddu_vv_tu: - case RISCVVector::BI__builtin_rvv_vaaddu_vx_tu: - case RISCVVector::BI__builtin_rvv_vaadd_vv_tu: - case RISCVVector::BI__builtin_rvv_vaadd_vx_tu: - case RISCVVector::BI__builtin_rvv_vasubu_vv_tu: - case RISCVVector::BI__builtin_rvv_vasubu_vx_tu: - case RISCVVector::BI__builtin_rvv_vasub_vv_tu: - case RISCVVector::BI__builtin_rvv_vasub_vx_tu: - case RISCVVector::BI__builtin_rvv_vsmul_vv_tu: - case RISCVVector::BI__builtin_rvv_vsmul_vx_tu: - case RISCVVector::BI__builtin_rvv_vssra_vv_tu: - case RISCVVector::BI__builtin_rvv_vssra_vx_tu: - case RISCVVector::BI__builtin_rvv_vssrl_vv_tu: - case RISCVVector::BI__builtin_rvv_vssrl_vx_tu: - case RISCVVector::BI__builtin_rvv_vnclip_wv_tu: - case RISCVVector::BI__builtin_rvv_vnclip_wx_tu: - case RISCVVector::BI__builtin_rvv_vnclipu_wv_tu: - case RISCVVector::BI__builtin_rvv_vnclipu_wx_tu: - case RISCVVector::BI__builtin_rvv_vaaddu_vv_m: - case RISCVVector::BI__builtin_rvv_vaaddu_vx_m: - case RISCVVector::BI__builtin_rvv_vaadd_vv_m: - case RISCVVector::BI__builtin_rvv_vaadd_vx_m: - case RISCVVector::BI__builtin_rvv_vasubu_vv_m: - case RISCVVector::BI__builtin_rvv_vasubu_vx_m: - case RISCVVector::BI__builtin_rvv_vasub_vv_m: - case RISCVVector::BI__builtin_rvv_vasub_vx_m: - case RISCVVector::BI__builtin_rvv_vsmul_vv_m: - case RISCVVector::BI__builtin_rvv_vsmul_vx_m: - case RISCVVector::BI__builtin_rvv_vssra_vv_m: - case RISCVVector::BI__builtin_rvv_vssra_vx_m: - case RISCVVector::BI__builtin_rvv_vssrl_vv_m: - case RISCVVector::BI__builtin_rvv_vssrl_vx_m: - case RISCVVector::BI__builtin_rvv_vnclip_wv_m: - case RISCVVector::BI__builtin_rvv_vnclip_wx_m: - case RISCVVector::BI__builtin_rvv_vnclipu_wv_m: - case RISCVVector::BI__builtin_rvv_vnclipu_wx_m: - return BuiltinConstantArgRange(TheCall, 3, 0, 3); - case RISCVVector::BI__builtin_rvv_vaaddu_vv_tum: - case RISCVVector::BI__builtin_rvv_vaaddu_vv_tumu: - case RISCVVector::BI__builtin_rvv_vaaddu_vv_mu: - case RISCVVector::BI__builtin_rvv_vaaddu_vx_tum: - case RISCVVector::BI__builtin_rvv_vaaddu_vx_tumu: - case RISCVVector::BI__builtin_rvv_vaaddu_vx_mu: - case RISCVVector::BI__builtin_rvv_vaadd_vv_tum: - case RISCVVector::BI__builtin_rvv_vaadd_vv_tumu: - case RISCVVector::BI__builtin_rvv_vaadd_vv_mu: - case RISCVVector::BI__builtin_rvv_vaadd_vx_tum: - case RISCVVector::BI__builtin_rvv_vaadd_vx_tumu: - case RISCVVector::BI__builtin_rvv_vaadd_vx_mu: - case RISCVVector::BI__builtin_rvv_vasubu_vv_tum: - case RISCVVector::BI__builtin_rvv_vasubu_vv_tumu: - case RISCVVector::BI__builtin_rvv_vasubu_vv_mu: - case RISCVVector::BI__builtin_rvv_vasubu_vx_tum: - case RISCVVector::BI__builtin_rvv_vasubu_vx_tumu: - case RISCVVector::BI__builtin_rvv_vasubu_vx_mu: - case RISCVVector::BI__builtin_rvv_vasub_vv_tum: - case RISCVVector::BI__builtin_rvv_vasub_vv_tumu: - case RISCVVector::BI__builtin_rvv_vasub_vv_mu: - case RISCVVector::BI__builtin_rvv_vasub_vx_tum: - case RISCVVector::BI__builtin_rvv_vasub_vx_tumu: - case RISCVVector::BI__builtin_rvv_vasub_vx_mu: - case RISCVVector::BI__builtin_rvv_vsmul_vv_mu: - case RISCVVector::BI__builtin_rvv_vsmul_vx_mu: - case RISCVVector::BI__builtin_rvv_vssra_vv_mu: - case RISCVVector::BI__builtin_rvv_vssra_vx_mu: - case RISCVVector::BI__builtin_rvv_vssrl_vv_mu: - case RISCVVector::BI__builtin_rvv_vssrl_vx_mu: - case RISCVVector::BI__builtin_rvv_vnclip_wv_mu: - case RISCVVector::BI__builtin_rvv_vnclip_wx_mu: - case RISCVVector::BI__builtin_rvv_vnclipu_wv_mu: - case RISCVVector::BI__builtin_rvv_vnclipu_wx_mu: - case RISCVVector::BI__builtin_rvv_vsmul_vv_tum: - case RISCVVector::BI__builtin_rvv_vsmul_vx_tum: - case RISCVVector::BI__builtin_rvv_vssra_vv_tum: - case RISCVVector::BI__builtin_rvv_vssra_vx_tum: - case RISCVVector::BI__builtin_rvv_vssrl_vv_tum: - case RISCVVector::BI__builtin_rvv_vssrl_vx_tum: - case RISCVVector::BI__builtin_rvv_vnclip_wv_tum: - case RISCVVector::BI__builtin_rvv_vnclip_wx_tum: - case RISCVVector::BI__builtin_rvv_vnclipu_wv_tum: - case RISCVVector::BI__builtin_rvv_vnclipu_wx_tum: - case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu: - case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu: - case RISCVVector::BI__builtin_rvv_vssra_vv_tumu: - case RISCVVector::BI__builtin_rvv_vssra_vx_tumu: - case RISCVVector::BI__builtin_rvv_vssrl_vv_tumu: - case RISCVVector::BI__builtin_rvv_vssrl_vx_tumu: - case RISCVVector::BI__builtin_rvv_vnclip_wv_tumu: - case RISCVVector::BI__builtin_rvv_vnclip_wx_tumu: - case RISCVVector::BI__builtin_rvv_vnclipu_wv_tumu: - case RISCVVector::BI__builtin_rvv_vnclipu_wx_tumu: - return BuiltinConstantArgRange(TheCall, 4, 0, 3); - case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm: - case RISCVVector::BI__builtin_rvv_vfrec7_v_rm: - case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm: - case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm: - case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm: - case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm: - case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm: - case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm: - case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm: - case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm: - case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm: - case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm: - case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm: - return BuiltinConstantArgRange(TheCall, 1, 0, 4); - case RISCVVector::BI__builtin_rvv_vfadd_vv_rm: - case RISCVVector::BI__builtin_rvv_vfadd_vf_rm: - case RISCVVector::BI__builtin_rvv_vfsub_vv_rm: - case RISCVVector::BI__builtin_rvv_vfsub_vf_rm: - case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm: - case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm: - case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm: - case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm: - case RISCVVector::BI__builtin_rvv_vfmul_vv_rm: - case RISCVVector::BI__builtin_rvv_vfmul_vf_rm: - case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm: - case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm: - case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm: - case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm: - case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm: - case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm: - case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm: - case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tu: - case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tu: - case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tu: - case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_m: - case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_m: - case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_m: - case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_m: - case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_m: - case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_m: - return BuiltinConstantArgRange(TheCall, 2, 0, 4); - case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tu: - case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm: - case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm: - case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm: - case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm: - case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm: - case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm: - case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm: - case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm: - case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm: - case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm: - case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm: - case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm: - case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm: - case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm: - case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm: - case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm: - case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tu: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tu: - case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_m: - case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_m: - case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_m: - case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_m: - case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_m: - case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tum: - case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tum: - case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tum: - case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tum: - case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tum: - case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tum: - case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_mu: - case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_mu: - case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_mu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_mu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_mu: - case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_mu: - return BuiltinConstantArgRange(TheCall, 3, 0, 4); - case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_m: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_m: - case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tum: - case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tum: - case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tum: - case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tum: - case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tumu: - case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_mu: - case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_mu: - return BuiltinConstantArgRange(TheCall, 4, 0, 4); - case RISCV::BI__builtin_riscv_ntl_load: - case RISCV::BI__builtin_riscv_ntl_store: - DeclRefExpr *DRE = - cast(TheCall->getCallee()->IgnoreParenCasts()); - assert((BuiltinID == RISCV::BI__builtin_riscv_ntl_store || - BuiltinID == RISCV::BI__builtin_riscv_ntl_load) && - "Unexpected RISC-V nontemporal load/store builtin!"); - bool IsStore = BuiltinID == RISCV::BI__builtin_riscv_ntl_store; - unsigned NumArgs = IsStore ? 3 : 2; - - if (checkArgCountAtLeast(*this, TheCall, NumArgs - 1)) - return true; - - if (checkArgCountAtMost(*this, TheCall, NumArgs)) - return true; - - // Domain value should be compile-time constant. - // 2 <= domain <= 5 - if (TheCall->getNumArgs() == NumArgs && - BuiltinConstantArgRange(TheCall, NumArgs - 1, 2, 5)) - return true; - - Expr *PointerArg = TheCall->getArg(0); - ExprResult PointerArgResult = - DefaultFunctionArrayLvalueConversion(PointerArg); - - if (PointerArgResult.isInvalid()) - return true; - PointerArg = PointerArgResult.get(); - - const PointerType *PtrType = PointerArg->getType()->getAs(); - if (!PtrType) { - Diag(DRE->getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer) - << PointerArg->getType() << PointerArg->getSourceRange(); - return true; - } - - QualType ValType = PtrType->getPointeeType(); - ValType = ValType.getUnqualifiedType(); - if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && - !ValType->isBlockPointerType() && !ValType->isFloatingType() && - !ValType->isVectorType() && !ValType->isRVVSizelessBuiltinType()) { - Diag(DRE->getBeginLoc(), - diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector) - << PointerArg->getType() << PointerArg->getSourceRange(); - return true; - } - - if (!IsStore) { - TheCall->setType(ValType); - return false; - } - - ExprResult ValArg = TheCall->getArg(1); - InitializedEntity Entity = InitializedEntity::InitializeParameter( - Context, ValType, /*consume*/ false); - ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg); - if (ValArg.isInvalid()) - return true; - - TheCall->setArg(1, ValArg.get()); - TheCall->setType(Context.VoidTy); - return false; - } - - return false; -} - bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == SystemZ::BI__builtin_tabort) { @@ -6708,38 +5872,6 @@ bool Sema::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, return false; } -void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D, - const llvm::StringMap &FeatureMap) { - ASTContext::BuiltinVectorTypeInfo Info = - Context.getBuiltinVectorTypeInfo(Ty->castAs()); - unsigned EltSize = Context.getTypeSize(Info.ElementType); - unsigned MinElts = Info.EC.getKnownMinValue(); - - if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Double) && - !FeatureMap.lookup("zve64d")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64d"; - // (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at - // least zve64x - else if (((EltSize == 64 && Info.ElementType->isIntegerType()) || - MinElts == 1) && - !FeatureMap.lookup("zve64x")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x"; - else if (Info.ElementType->isFloat16Type() && !FeatureMap.lookup("zvfh") && - !FeatureMap.lookup("zvfhmin")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) - << Ty << "zvfh or zvfhmin"; - else if (Info.ElementType->isBFloat16Type() && - !FeatureMap.lookup("experimental-zvfbfmin")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin"; - else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) && - !FeatureMap.lookup("zve32f")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f"; - // Given that caller already checked isRVVType() before calling this function, - // if we don't have at least zve32x supported, then we need to emit error. - else if (!FeatureMap.lookup("zve32x")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x"; -} - bool Sema::CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall) { @@ -6748,862 +5880,12 @@ bool Sema::CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, case NVPTX::BI__nvvm_cp_async_ca_shared_global_8: case NVPTX::BI__nvvm_cp_async_ca_shared_global_16: case NVPTX::BI__nvvm_cp_async_cg_shared_global_16: - return checkArgCountAtMost(*this, TheCall, 3); + return checkArgCountAtMost(TheCall, 3); } return false; } -// Check if the rounding mode is legal. -bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { - // Indicates if this instruction has rounding control or just SAE. - bool HasRC = false; - - unsigned ArgNum = 0; - switch (BuiltinID) { - default: - return false; - case X86::BI__builtin_ia32_vcvttsd2si32: - case X86::BI__builtin_ia32_vcvttsd2si64: - case X86::BI__builtin_ia32_vcvttsd2usi32: - case X86::BI__builtin_ia32_vcvttsd2usi64: - case X86::BI__builtin_ia32_vcvttss2si32: - case X86::BI__builtin_ia32_vcvttss2si64: - case X86::BI__builtin_ia32_vcvttss2usi32: - case X86::BI__builtin_ia32_vcvttss2usi64: - case X86::BI__builtin_ia32_vcvttsh2si32: - case X86::BI__builtin_ia32_vcvttsh2si64: - case X86::BI__builtin_ia32_vcvttsh2usi32: - case X86::BI__builtin_ia32_vcvttsh2usi64: - ArgNum = 1; - break; - case X86::BI__builtin_ia32_maxpd512: - case X86::BI__builtin_ia32_maxps512: - case X86::BI__builtin_ia32_minpd512: - case X86::BI__builtin_ia32_minps512: - case X86::BI__builtin_ia32_maxph512: - case X86::BI__builtin_ia32_minph512: - ArgNum = 2; - break; - case X86::BI__builtin_ia32_vcvtph2pd512_mask: - case X86::BI__builtin_ia32_vcvtph2psx512_mask: - case X86::BI__builtin_ia32_cvtps2pd512_mask: - case X86::BI__builtin_ia32_cvttpd2dq512_mask: - case X86::BI__builtin_ia32_cvttpd2qq512_mask: - case X86::BI__builtin_ia32_cvttpd2udq512_mask: - case X86::BI__builtin_ia32_cvttpd2uqq512_mask: - case X86::BI__builtin_ia32_cvttps2dq512_mask: - case X86::BI__builtin_ia32_cvttps2qq512_mask: - case X86::BI__builtin_ia32_cvttps2udq512_mask: - case X86::BI__builtin_ia32_cvttps2uqq512_mask: - case X86::BI__builtin_ia32_vcvttph2w512_mask: - case X86::BI__builtin_ia32_vcvttph2uw512_mask: - case X86::BI__builtin_ia32_vcvttph2dq512_mask: - case X86::BI__builtin_ia32_vcvttph2udq512_mask: - case X86::BI__builtin_ia32_vcvttph2qq512_mask: - case X86::BI__builtin_ia32_vcvttph2uqq512_mask: - case X86::BI__builtin_ia32_exp2pd_mask: - case X86::BI__builtin_ia32_exp2ps_mask: - case X86::BI__builtin_ia32_getexppd512_mask: - case X86::BI__builtin_ia32_getexpps512_mask: - case X86::BI__builtin_ia32_getexpph512_mask: - case X86::BI__builtin_ia32_rcp28pd_mask: - case X86::BI__builtin_ia32_rcp28ps_mask: - case X86::BI__builtin_ia32_rsqrt28pd_mask: - case X86::BI__builtin_ia32_rsqrt28ps_mask: - case X86::BI__builtin_ia32_vcomisd: - case X86::BI__builtin_ia32_vcomiss: - case X86::BI__builtin_ia32_vcomish: - case X86::BI__builtin_ia32_vcvtph2ps512_mask: - ArgNum = 3; - break; - case X86::BI__builtin_ia32_cmppd512_mask: - case X86::BI__builtin_ia32_cmpps512_mask: - case X86::BI__builtin_ia32_cmpsd_mask: - case X86::BI__builtin_ia32_cmpss_mask: - case X86::BI__builtin_ia32_cmpsh_mask: - case X86::BI__builtin_ia32_vcvtsh2sd_round_mask: - case X86::BI__builtin_ia32_vcvtsh2ss_round_mask: - case X86::BI__builtin_ia32_cvtss2sd_round_mask: - case X86::BI__builtin_ia32_getexpsd128_round_mask: - case X86::BI__builtin_ia32_getexpss128_round_mask: - case X86::BI__builtin_ia32_getexpsh128_round_mask: - case X86::BI__builtin_ia32_getmantpd512_mask: - case X86::BI__builtin_ia32_getmantps512_mask: - case X86::BI__builtin_ia32_getmantph512_mask: - case X86::BI__builtin_ia32_maxsd_round_mask: - case X86::BI__builtin_ia32_maxss_round_mask: - case X86::BI__builtin_ia32_maxsh_round_mask: - case X86::BI__builtin_ia32_minsd_round_mask: - case X86::BI__builtin_ia32_minss_round_mask: - case X86::BI__builtin_ia32_minsh_round_mask: - case X86::BI__builtin_ia32_rcp28sd_round_mask: - case X86::BI__builtin_ia32_rcp28ss_round_mask: - case X86::BI__builtin_ia32_reducepd512_mask: - case X86::BI__builtin_ia32_reduceps512_mask: - case X86::BI__builtin_ia32_reduceph512_mask: - case X86::BI__builtin_ia32_rndscalepd_mask: - case X86::BI__builtin_ia32_rndscaleps_mask: - case X86::BI__builtin_ia32_rndscaleph_mask: - case X86::BI__builtin_ia32_rsqrt28sd_round_mask: - case X86::BI__builtin_ia32_rsqrt28ss_round_mask: - ArgNum = 4; - break; - case X86::BI__builtin_ia32_fixupimmpd512_mask: - case X86::BI__builtin_ia32_fixupimmpd512_maskz: - case X86::BI__builtin_ia32_fixupimmps512_mask: - case X86::BI__builtin_ia32_fixupimmps512_maskz: - case X86::BI__builtin_ia32_fixupimmsd_mask: - case X86::BI__builtin_ia32_fixupimmsd_maskz: - case X86::BI__builtin_ia32_fixupimmss_mask: - case X86::BI__builtin_ia32_fixupimmss_maskz: - case X86::BI__builtin_ia32_getmantsd_round_mask: - case X86::BI__builtin_ia32_getmantss_round_mask: - case X86::BI__builtin_ia32_getmantsh_round_mask: - case X86::BI__builtin_ia32_rangepd512_mask: - case X86::BI__builtin_ia32_rangeps512_mask: - case X86::BI__builtin_ia32_rangesd128_round_mask: - case X86::BI__builtin_ia32_rangess128_round_mask: - case X86::BI__builtin_ia32_reducesd_mask: - case X86::BI__builtin_ia32_reducess_mask: - case X86::BI__builtin_ia32_reducesh_mask: - case X86::BI__builtin_ia32_rndscalesd_round_mask: - case X86::BI__builtin_ia32_rndscaless_round_mask: - case X86::BI__builtin_ia32_rndscalesh_round_mask: - ArgNum = 5; - break; - case X86::BI__builtin_ia32_vcvtsd2si64: - case X86::BI__builtin_ia32_vcvtsd2si32: - case X86::BI__builtin_ia32_vcvtsd2usi32: - case X86::BI__builtin_ia32_vcvtsd2usi64: - case X86::BI__builtin_ia32_vcvtss2si32: - case X86::BI__builtin_ia32_vcvtss2si64: - case X86::BI__builtin_ia32_vcvtss2usi32: - case X86::BI__builtin_ia32_vcvtss2usi64: - case X86::BI__builtin_ia32_vcvtsh2si32: - case X86::BI__builtin_ia32_vcvtsh2si64: - case X86::BI__builtin_ia32_vcvtsh2usi32: - case X86::BI__builtin_ia32_vcvtsh2usi64: - case X86::BI__builtin_ia32_sqrtpd512: - case X86::BI__builtin_ia32_sqrtps512: - case X86::BI__builtin_ia32_sqrtph512: - ArgNum = 1; - HasRC = true; - break; - case X86::BI__builtin_ia32_addph512: - case X86::BI__builtin_ia32_divph512: - case X86::BI__builtin_ia32_mulph512: - case X86::BI__builtin_ia32_subph512: - case X86::BI__builtin_ia32_addpd512: - case X86::BI__builtin_ia32_addps512: - case X86::BI__builtin_ia32_divpd512: - case X86::BI__builtin_ia32_divps512: - case X86::BI__builtin_ia32_mulpd512: - case X86::BI__builtin_ia32_mulps512: - case X86::BI__builtin_ia32_subpd512: - case X86::BI__builtin_ia32_subps512: - case X86::BI__builtin_ia32_cvtsi2sd64: - case X86::BI__builtin_ia32_cvtsi2ss32: - case X86::BI__builtin_ia32_cvtsi2ss64: - case X86::BI__builtin_ia32_cvtusi2sd64: - case X86::BI__builtin_ia32_cvtusi2ss32: - case X86::BI__builtin_ia32_cvtusi2ss64: - case X86::BI__builtin_ia32_vcvtusi2sh: - case X86::BI__builtin_ia32_vcvtusi642sh: - case X86::BI__builtin_ia32_vcvtsi2sh: - case X86::BI__builtin_ia32_vcvtsi642sh: - ArgNum = 2; - HasRC = true; - break; - case X86::BI__builtin_ia32_cvtdq2ps512_mask: - case X86::BI__builtin_ia32_cvtudq2ps512_mask: - case X86::BI__builtin_ia32_vcvtpd2ph512_mask: - case X86::BI__builtin_ia32_vcvtps2phx512_mask: - case X86::BI__builtin_ia32_cvtpd2ps512_mask: - case X86::BI__builtin_ia32_cvtpd2dq512_mask: - case X86::BI__builtin_ia32_cvtpd2qq512_mask: - case X86::BI__builtin_ia32_cvtpd2udq512_mask: - case X86::BI__builtin_ia32_cvtpd2uqq512_mask: - case X86::BI__builtin_ia32_cvtps2dq512_mask: - case X86::BI__builtin_ia32_cvtps2qq512_mask: - case X86::BI__builtin_ia32_cvtps2udq512_mask: - case X86::BI__builtin_ia32_cvtps2uqq512_mask: - case X86::BI__builtin_ia32_cvtqq2pd512_mask: - case X86::BI__builtin_ia32_cvtqq2ps512_mask: - case X86::BI__builtin_ia32_cvtuqq2pd512_mask: - case X86::BI__builtin_ia32_cvtuqq2ps512_mask: - case X86::BI__builtin_ia32_vcvtdq2ph512_mask: - case X86::BI__builtin_ia32_vcvtudq2ph512_mask: - case X86::BI__builtin_ia32_vcvtw2ph512_mask: - case X86::BI__builtin_ia32_vcvtuw2ph512_mask: - case X86::BI__builtin_ia32_vcvtph2w512_mask: - case X86::BI__builtin_ia32_vcvtph2uw512_mask: - case X86::BI__builtin_ia32_vcvtph2dq512_mask: - case X86::BI__builtin_ia32_vcvtph2udq512_mask: - case X86::BI__builtin_ia32_vcvtph2qq512_mask: - case X86::BI__builtin_ia32_vcvtph2uqq512_mask: - case X86::BI__builtin_ia32_vcvtqq2ph512_mask: - case X86::BI__builtin_ia32_vcvtuqq2ph512_mask: - ArgNum = 3; - HasRC = true; - break; - case X86::BI__builtin_ia32_addsh_round_mask: - case X86::BI__builtin_ia32_addss_round_mask: - case X86::BI__builtin_ia32_addsd_round_mask: - case X86::BI__builtin_ia32_divsh_round_mask: - case X86::BI__builtin_ia32_divss_round_mask: - case X86::BI__builtin_ia32_divsd_round_mask: - case X86::BI__builtin_ia32_mulsh_round_mask: - case X86::BI__builtin_ia32_mulss_round_mask: - case X86::BI__builtin_ia32_mulsd_round_mask: - case X86::BI__builtin_ia32_subsh_round_mask: - case X86::BI__builtin_ia32_subss_round_mask: - case X86::BI__builtin_ia32_subsd_round_mask: - case X86::BI__builtin_ia32_scalefph512_mask: - case X86::BI__builtin_ia32_scalefpd512_mask: - case X86::BI__builtin_ia32_scalefps512_mask: - case X86::BI__builtin_ia32_scalefsd_round_mask: - case X86::BI__builtin_ia32_scalefss_round_mask: - case X86::BI__builtin_ia32_scalefsh_round_mask: - case X86::BI__builtin_ia32_cvtsd2ss_round_mask: - case X86::BI__builtin_ia32_vcvtss2sh_round_mask: - case X86::BI__builtin_ia32_vcvtsd2sh_round_mask: - case X86::BI__builtin_ia32_sqrtsd_round_mask: - case X86::BI__builtin_ia32_sqrtss_round_mask: - case X86::BI__builtin_ia32_sqrtsh_round_mask: - case X86::BI__builtin_ia32_vfmaddsd3_mask: - case X86::BI__builtin_ia32_vfmaddsd3_maskz: - case X86::BI__builtin_ia32_vfmaddsd3_mask3: - case X86::BI__builtin_ia32_vfmaddss3_mask: - case X86::BI__builtin_ia32_vfmaddss3_maskz: - case X86::BI__builtin_ia32_vfmaddss3_mask3: - case X86::BI__builtin_ia32_vfmaddsh3_mask: - case X86::BI__builtin_ia32_vfmaddsh3_maskz: - case X86::BI__builtin_ia32_vfmaddsh3_mask3: - case X86::BI__builtin_ia32_vfmaddpd512_mask: - case X86::BI__builtin_ia32_vfmaddpd512_maskz: - case X86::BI__builtin_ia32_vfmaddpd512_mask3: - case X86::BI__builtin_ia32_vfmsubpd512_mask3: - case X86::BI__builtin_ia32_vfmaddps512_mask: - case X86::BI__builtin_ia32_vfmaddps512_maskz: - case X86::BI__builtin_ia32_vfmaddps512_mask3: - case X86::BI__builtin_ia32_vfmsubps512_mask3: - case X86::BI__builtin_ia32_vfmaddph512_mask: - case X86::BI__builtin_ia32_vfmaddph512_maskz: - case X86::BI__builtin_ia32_vfmaddph512_mask3: - case X86::BI__builtin_ia32_vfmsubph512_mask3: - case X86::BI__builtin_ia32_vfmaddsubpd512_mask: - case X86::BI__builtin_ia32_vfmaddsubpd512_maskz: - case X86::BI__builtin_ia32_vfmaddsubpd512_mask3: - case X86::BI__builtin_ia32_vfmsubaddpd512_mask3: - case X86::BI__builtin_ia32_vfmaddsubps512_mask: - case X86::BI__builtin_ia32_vfmaddsubps512_maskz: - case X86::BI__builtin_ia32_vfmaddsubps512_mask3: - case X86::BI__builtin_ia32_vfmsubaddps512_mask3: - case X86::BI__builtin_ia32_vfmaddsubph512_mask: - case X86::BI__builtin_ia32_vfmaddsubph512_maskz: - case X86::BI__builtin_ia32_vfmaddsubph512_mask3: - case X86::BI__builtin_ia32_vfmsubaddph512_mask3: - case X86::BI__builtin_ia32_vfmaddcsh_mask: - case X86::BI__builtin_ia32_vfmaddcsh_round_mask: - case X86::BI__builtin_ia32_vfmaddcsh_round_mask3: - case X86::BI__builtin_ia32_vfmaddcph512_mask: - case X86::BI__builtin_ia32_vfmaddcph512_maskz: - case X86::BI__builtin_ia32_vfmaddcph512_mask3: - case X86::BI__builtin_ia32_vfcmaddcsh_mask: - case X86::BI__builtin_ia32_vfcmaddcsh_round_mask: - case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3: - case X86::BI__builtin_ia32_vfcmaddcph512_mask: - case X86::BI__builtin_ia32_vfcmaddcph512_maskz: - case X86::BI__builtin_ia32_vfcmaddcph512_mask3: - case X86::BI__builtin_ia32_vfmulcsh_mask: - case X86::BI__builtin_ia32_vfmulcph512_mask: - case X86::BI__builtin_ia32_vfcmulcsh_mask: - case X86::BI__builtin_ia32_vfcmulcph512_mask: - ArgNum = 4; - HasRC = true; - break; - } - - llvm::APSInt Result; - - // We can't check the value of a dependent argument. - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - return false; - - // Check constant-ness first. - if (BuiltinConstantArg(TheCall, ArgNum, Result)) - return true; - - // Make sure rounding mode is either ROUND_CUR_DIRECTION or ROUND_NO_EXC bit - // is set. If the intrinsic has rounding control(bits 1:0), make sure its only - // combined with ROUND_NO_EXC. If the intrinsic does not have rounding - // control, allow ROUND_NO_EXC and ROUND_CUR_DIRECTION together. - if (Result == 4/*ROUND_CUR_DIRECTION*/ || - Result == 8/*ROUND_NO_EXC*/ || - (!HasRC && Result == 12/*ROUND_CUR_DIRECTION|ROUND_NO_EXC*/) || - (HasRC && Result.getZExtValue() >= 8 && Result.getZExtValue() <= 11)) - return false; - - return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_rounding) - << Arg->getSourceRange(); -} - -// Check if the gather/scatter scale is legal. -bool Sema::CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, - CallExpr *TheCall) { - unsigned ArgNum = 0; - switch (BuiltinID) { - default: - return false; - case X86::BI__builtin_ia32_gatherpfdpd: - case X86::BI__builtin_ia32_gatherpfdps: - case X86::BI__builtin_ia32_gatherpfqpd: - case X86::BI__builtin_ia32_gatherpfqps: - case X86::BI__builtin_ia32_scatterpfdpd: - case X86::BI__builtin_ia32_scatterpfdps: - case X86::BI__builtin_ia32_scatterpfqpd: - case X86::BI__builtin_ia32_scatterpfqps: - ArgNum = 3; - break; - case X86::BI__builtin_ia32_gatherd_pd: - case X86::BI__builtin_ia32_gatherd_pd256: - case X86::BI__builtin_ia32_gatherq_pd: - case X86::BI__builtin_ia32_gatherq_pd256: - case X86::BI__builtin_ia32_gatherd_ps: - case X86::BI__builtin_ia32_gatherd_ps256: - case X86::BI__builtin_ia32_gatherq_ps: - case X86::BI__builtin_ia32_gatherq_ps256: - case X86::BI__builtin_ia32_gatherd_q: - case X86::BI__builtin_ia32_gatherd_q256: - case X86::BI__builtin_ia32_gatherq_q: - case X86::BI__builtin_ia32_gatherq_q256: - case X86::BI__builtin_ia32_gatherd_d: - case X86::BI__builtin_ia32_gatherd_d256: - case X86::BI__builtin_ia32_gatherq_d: - case X86::BI__builtin_ia32_gatherq_d256: - case X86::BI__builtin_ia32_gather3div2df: - case X86::BI__builtin_ia32_gather3div2di: - case X86::BI__builtin_ia32_gather3div4df: - case X86::BI__builtin_ia32_gather3div4di: - case X86::BI__builtin_ia32_gather3div4sf: - case X86::BI__builtin_ia32_gather3div4si: - case X86::BI__builtin_ia32_gather3div8sf: - case X86::BI__builtin_ia32_gather3div8si: - case X86::BI__builtin_ia32_gather3siv2df: - case X86::BI__builtin_ia32_gather3siv2di: - case X86::BI__builtin_ia32_gather3siv4df: - case X86::BI__builtin_ia32_gather3siv4di: - case X86::BI__builtin_ia32_gather3siv4sf: - case X86::BI__builtin_ia32_gather3siv4si: - case X86::BI__builtin_ia32_gather3siv8sf: - case X86::BI__builtin_ia32_gather3siv8si: - case X86::BI__builtin_ia32_gathersiv8df: - case X86::BI__builtin_ia32_gathersiv16sf: - case X86::BI__builtin_ia32_gatherdiv8df: - case X86::BI__builtin_ia32_gatherdiv16sf: - case X86::BI__builtin_ia32_gathersiv8di: - case X86::BI__builtin_ia32_gathersiv16si: - case X86::BI__builtin_ia32_gatherdiv8di: - case X86::BI__builtin_ia32_gatherdiv16si: - case X86::BI__builtin_ia32_scatterdiv2df: - case X86::BI__builtin_ia32_scatterdiv2di: - case X86::BI__builtin_ia32_scatterdiv4df: - case X86::BI__builtin_ia32_scatterdiv4di: - case X86::BI__builtin_ia32_scatterdiv4sf: - case X86::BI__builtin_ia32_scatterdiv4si: - case X86::BI__builtin_ia32_scatterdiv8sf: - case X86::BI__builtin_ia32_scatterdiv8si: - case X86::BI__builtin_ia32_scattersiv2df: - case X86::BI__builtin_ia32_scattersiv2di: - case X86::BI__builtin_ia32_scattersiv4df: - case X86::BI__builtin_ia32_scattersiv4di: - case X86::BI__builtin_ia32_scattersiv4sf: - case X86::BI__builtin_ia32_scattersiv4si: - case X86::BI__builtin_ia32_scattersiv8sf: - case X86::BI__builtin_ia32_scattersiv8si: - case X86::BI__builtin_ia32_scattersiv8df: - case X86::BI__builtin_ia32_scattersiv16sf: - case X86::BI__builtin_ia32_scatterdiv8df: - case X86::BI__builtin_ia32_scatterdiv16sf: - case X86::BI__builtin_ia32_scattersiv8di: - case X86::BI__builtin_ia32_scattersiv16si: - case X86::BI__builtin_ia32_scatterdiv8di: - case X86::BI__builtin_ia32_scatterdiv16si: - ArgNum = 4; - break; - } - - llvm::APSInt Result; - - // We can't check the value of a dependent argument. - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - return false; - - // Check constant-ness first. - if (BuiltinConstantArg(TheCall, ArgNum, Result)) - return true; - - if (Result == 1 || Result == 2 || Result == 4 || Result == 8) - return false; - - return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_scale) - << Arg->getSourceRange(); -} - -enum { TileRegLow = 0, TileRegHigh = 7 }; - -bool Sema::CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, - ArrayRef ArgNums) { - for (int ArgNum : ArgNums) { - if (BuiltinConstantArgRange(TheCall, ArgNum, TileRegLow, TileRegHigh)) - return true; - } - return false; -} - -bool Sema::CheckX86BuiltinTileDuplicate(CallExpr *TheCall, - ArrayRef ArgNums) { - // Because the max number of tile register is TileRegHigh + 1, so here we use - // each bit to represent the usage of them in bitset. - std::bitset ArgValues; - for (int ArgNum : ArgNums) { - Expr *Arg = TheCall->getArg(ArgNum); - if (Arg->isTypeDependent() || Arg->isValueDependent()) - continue; - - llvm::APSInt Result; - if (BuiltinConstantArg(TheCall, ArgNum, Result)) - return true; - int ArgExtValue = Result.getExtValue(); - assert((ArgExtValue >= TileRegLow && ArgExtValue <= TileRegHigh) && - "Incorrect tile register num."); - if (ArgValues.test(ArgExtValue)) - return Diag(TheCall->getBeginLoc(), - diag::err_x86_builtin_tile_arg_duplicate) - << TheCall->getArg(ArgNum)->getSourceRange(); - ArgValues.set(ArgExtValue); - } - return false; -} - -bool Sema::CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, - ArrayRef ArgNums) { - return CheckX86BuiltinTileArgumentsRange(TheCall, ArgNums) || - CheckX86BuiltinTileDuplicate(TheCall, ArgNums); -} - -bool Sema::CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall) { - switch (BuiltinID) { - default: - return false; - case X86::BI__builtin_ia32_tileloadd64: - case X86::BI__builtin_ia32_tileloaddt164: - case X86::BI__builtin_ia32_tilestored64: - case X86::BI__builtin_ia32_tilezero: - return CheckX86BuiltinTileArgumentsRange(TheCall, 0); - case X86::BI__builtin_ia32_tdpbssd: - case X86::BI__builtin_ia32_tdpbsud: - case X86::BI__builtin_ia32_tdpbusd: - case X86::BI__builtin_ia32_tdpbuud: - case X86::BI__builtin_ia32_tdpbf16ps: - case X86::BI__builtin_ia32_tdpfp16ps: - case X86::BI__builtin_ia32_tcmmimfp16ps: - case X86::BI__builtin_ia32_tcmmrlfp16ps: - return CheckX86BuiltinTileRangeAndDuplicate(TheCall, {0, 1, 2}); - } -} -static bool isX86_32Builtin(unsigned BuiltinID) { - // These builtins only work on x86-32 targets. - switch (BuiltinID) { - case X86::BI__builtin_ia32_readeflags_u32: - case X86::BI__builtin_ia32_writeeflags_u32: - return true; - } - - return false; -} - -bool Sema::CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, - CallExpr *TheCall) { - // Check for 32-bit only builtins on a 64-bit target. - const llvm::Triple &TT = TI.getTriple(); - if (TT.getArch() != llvm::Triple::x86 && isX86_32Builtin(BuiltinID)) - return Diag(TheCall->getCallee()->getBeginLoc(), - diag::err_32_bit_builtin_64_bit_tgt); - - // If the intrinsic has rounding or SAE make sure its valid. - if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall)) - return true; - - // If the intrinsic has a gather/scatter scale immediate make sure its valid. - if (CheckX86BuiltinGatherScatterScale(BuiltinID, TheCall)) - return true; - - // If the intrinsic has a tile arguments, make sure they are valid. - if (CheckX86BuiltinTileArguments(BuiltinID, TheCall)) - return true; - - // For intrinsics which take an immediate value as part of the instruction, - // range check them here. - int i = 0, l = 0, u = 0; - switch (BuiltinID) { - default: - return false; - case X86::BI__builtin_ia32_vec_ext_v2si: - case X86::BI__builtin_ia32_vec_ext_v2di: - case X86::BI__builtin_ia32_vextractf128_pd256: - case X86::BI__builtin_ia32_vextractf128_ps256: - case X86::BI__builtin_ia32_vextractf128_si256: - case X86::BI__builtin_ia32_extract128i256: - case X86::BI__builtin_ia32_extractf64x4_mask: - case X86::BI__builtin_ia32_extracti64x4_mask: - case X86::BI__builtin_ia32_extractf32x8_mask: - case X86::BI__builtin_ia32_extracti32x8_mask: - case X86::BI__builtin_ia32_extractf64x2_256_mask: - case X86::BI__builtin_ia32_extracti64x2_256_mask: - case X86::BI__builtin_ia32_extractf32x4_256_mask: - case X86::BI__builtin_ia32_extracti32x4_256_mask: - i = 1; l = 0; u = 1; - break; - case X86::BI__builtin_ia32_vec_set_v2di: - case X86::BI__builtin_ia32_vinsertf128_pd256: - case X86::BI__builtin_ia32_vinsertf128_ps256: - case X86::BI__builtin_ia32_vinsertf128_si256: - case X86::BI__builtin_ia32_insert128i256: - case X86::BI__builtin_ia32_insertf32x8: - case X86::BI__builtin_ia32_inserti32x8: - case X86::BI__builtin_ia32_insertf64x4: - case X86::BI__builtin_ia32_inserti64x4: - case X86::BI__builtin_ia32_insertf64x2_256: - case X86::BI__builtin_ia32_inserti64x2_256: - case X86::BI__builtin_ia32_insertf32x4_256: - case X86::BI__builtin_ia32_inserti32x4_256: - i = 2; l = 0; u = 1; - break; - case X86::BI__builtin_ia32_vpermilpd: - case X86::BI__builtin_ia32_vec_ext_v4hi: - case X86::BI__builtin_ia32_vec_ext_v4si: - case X86::BI__builtin_ia32_vec_ext_v4sf: - case X86::BI__builtin_ia32_vec_ext_v4di: - case X86::BI__builtin_ia32_extractf32x4_mask: - case X86::BI__builtin_ia32_extracti32x4_mask: - case X86::BI__builtin_ia32_extractf64x2_512_mask: - case X86::BI__builtin_ia32_extracti64x2_512_mask: - i = 1; l = 0; u = 3; - break; - case X86::BI_mm_prefetch: - case X86::BI__builtin_ia32_vec_ext_v8hi: - case X86::BI__builtin_ia32_vec_ext_v8si: - i = 1; l = 0; u = 7; - break; - case X86::BI__builtin_ia32_sha1rnds4: - case X86::BI__builtin_ia32_blendpd: - case X86::BI__builtin_ia32_shufpd: - case X86::BI__builtin_ia32_vec_set_v4hi: - case X86::BI__builtin_ia32_vec_set_v4si: - case X86::BI__builtin_ia32_vec_set_v4di: - case X86::BI__builtin_ia32_shuf_f32x4_256: - case X86::BI__builtin_ia32_shuf_f64x2_256: - case X86::BI__builtin_ia32_shuf_i32x4_256: - case X86::BI__builtin_ia32_shuf_i64x2_256: - case X86::BI__builtin_ia32_insertf64x2_512: - case X86::BI__builtin_ia32_inserti64x2_512: - case X86::BI__builtin_ia32_insertf32x4: - case X86::BI__builtin_ia32_inserti32x4: - i = 2; l = 0; u = 3; - break; - case X86::BI__builtin_ia32_vpermil2pd: - case X86::BI__builtin_ia32_vpermil2pd256: - case X86::BI__builtin_ia32_vpermil2ps: - case X86::BI__builtin_ia32_vpermil2ps256: - i = 3; l = 0; u = 3; - break; - case X86::BI__builtin_ia32_cmpb128_mask: - case X86::BI__builtin_ia32_cmpw128_mask: - case X86::BI__builtin_ia32_cmpd128_mask: - case X86::BI__builtin_ia32_cmpq128_mask: - case X86::BI__builtin_ia32_cmpb256_mask: - case X86::BI__builtin_ia32_cmpw256_mask: - case X86::BI__builtin_ia32_cmpd256_mask: - case X86::BI__builtin_ia32_cmpq256_mask: - case X86::BI__builtin_ia32_cmpb512_mask: - case X86::BI__builtin_ia32_cmpw512_mask: - case X86::BI__builtin_ia32_cmpd512_mask: - case X86::BI__builtin_ia32_cmpq512_mask: - case X86::BI__builtin_ia32_ucmpb128_mask: - case X86::BI__builtin_ia32_ucmpw128_mask: - case X86::BI__builtin_ia32_ucmpd128_mask: - case X86::BI__builtin_ia32_ucmpq128_mask: - case X86::BI__builtin_ia32_ucmpb256_mask: - case X86::BI__builtin_ia32_ucmpw256_mask: - case X86::BI__builtin_ia32_ucmpd256_mask: - case X86::BI__builtin_ia32_ucmpq256_mask: - case X86::BI__builtin_ia32_ucmpb512_mask: - case X86::BI__builtin_ia32_ucmpw512_mask: - case X86::BI__builtin_ia32_ucmpd512_mask: - case X86::BI__builtin_ia32_ucmpq512_mask: - case X86::BI__builtin_ia32_vpcomub: - case X86::BI__builtin_ia32_vpcomuw: - case X86::BI__builtin_ia32_vpcomud: - case X86::BI__builtin_ia32_vpcomuq: - case X86::BI__builtin_ia32_vpcomb: - case X86::BI__builtin_ia32_vpcomw: - case X86::BI__builtin_ia32_vpcomd: - case X86::BI__builtin_ia32_vpcomq: - case X86::BI__builtin_ia32_vec_set_v8hi: - case X86::BI__builtin_ia32_vec_set_v8si: - i = 2; l = 0; u = 7; - break; - case X86::BI__builtin_ia32_vpermilpd256: - case X86::BI__builtin_ia32_roundps: - case X86::BI__builtin_ia32_roundpd: - case X86::BI__builtin_ia32_roundps256: - case X86::BI__builtin_ia32_roundpd256: - case X86::BI__builtin_ia32_getmantpd128_mask: - case X86::BI__builtin_ia32_getmantpd256_mask: - case X86::BI__builtin_ia32_getmantps128_mask: - case X86::BI__builtin_ia32_getmantps256_mask: - case X86::BI__builtin_ia32_getmantpd512_mask: - case X86::BI__builtin_ia32_getmantps512_mask: - case X86::BI__builtin_ia32_getmantph128_mask: - case X86::BI__builtin_ia32_getmantph256_mask: - case X86::BI__builtin_ia32_getmantph512_mask: - case X86::BI__builtin_ia32_vec_ext_v16qi: - case X86::BI__builtin_ia32_vec_ext_v16hi: - i = 1; l = 0; u = 15; - break; - case X86::BI__builtin_ia32_pblendd128: - case X86::BI__builtin_ia32_blendps: - case X86::BI__builtin_ia32_blendpd256: - case X86::BI__builtin_ia32_shufpd256: - case X86::BI__builtin_ia32_roundss: - case X86::BI__builtin_ia32_roundsd: - case X86::BI__builtin_ia32_rangepd128_mask: - case X86::BI__builtin_ia32_rangepd256_mask: - case X86::BI__builtin_ia32_rangepd512_mask: - case X86::BI__builtin_ia32_rangeps128_mask: - case X86::BI__builtin_ia32_rangeps256_mask: - case X86::BI__builtin_ia32_rangeps512_mask: - case X86::BI__builtin_ia32_getmantsd_round_mask: - case X86::BI__builtin_ia32_getmantss_round_mask: - case X86::BI__builtin_ia32_getmantsh_round_mask: - case X86::BI__builtin_ia32_vec_set_v16qi: - case X86::BI__builtin_ia32_vec_set_v16hi: - i = 2; l = 0; u = 15; - break; - case X86::BI__builtin_ia32_vec_ext_v32qi: - i = 1; l = 0; u = 31; - break; - case X86::BI__builtin_ia32_cmpps: - case X86::BI__builtin_ia32_cmpss: - case X86::BI__builtin_ia32_cmppd: - case X86::BI__builtin_ia32_cmpsd: - case X86::BI__builtin_ia32_cmpps256: - case X86::BI__builtin_ia32_cmppd256: - case X86::BI__builtin_ia32_cmpps128_mask: - case X86::BI__builtin_ia32_cmppd128_mask: - case X86::BI__builtin_ia32_cmpps256_mask: - case X86::BI__builtin_ia32_cmppd256_mask: - case X86::BI__builtin_ia32_cmpps512_mask: - case X86::BI__builtin_ia32_cmppd512_mask: - case X86::BI__builtin_ia32_cmpsd_mask: - case X86::BI__builtin_ia32_cmpss_mask: - case X86::BI__builtin_ia32_vec_set_v32qi: - i = 2; l = 0; u = 31; - break; - case X86::BI__builtin_ia32_permdf256: - case X86::BI__builtin_ia32_permdi256: - case X86::BI__builtin_ia32_permdf512: - case X86::BI__builtin_ia32_permdi512: - case X86::BI__builtin_ia32_vpermilps: - case X86::BI__builtin_ia32_vpermilps256: - case X86::BI__builtin_ia32_vpermilpd512: - case X86::BI__builtin_ia32_vpermilps512: - case X86::BI__builtin_ia32_pshufd: - case X86::BI__builtin_ia32_pshufd256: - case X86::BI__builtin_ia32_pshufd512: - case X86::BI__builtin_ia32_pshufhw: - case X86::BI__builtin_ia32_pshufhw256: - case X86::BI__builtin_ia32_pshufhw512: - case X86::BI__builtin_ia32_pshuflw: - case X86::BI__builtin_ia32_pshuflw256: - case X86::BI__builtin_ia32_pshuflw512: - case X86::BI__builtin_ia32_vcvtps2ph: - case X86::BI__builtin_ia32_vcvtps2ph_mask: - case X86::BI__builtin_ia32_vcvtps2ph256: - case X86::BI__builtin_ia32_vcvtps2ph256_mask: - case X86::BI__builtin_ia32_vcvtps2ph512_mask: - case X86::BI__builtin_ia32_rndscaleps_128_mask: - case X86::BI__builtin_ia32_rndscalepd_128_mask: - case X86::BI__builtin_ia32_rndscaleps_256_mask: - case X86::BI__builtin_ia32_rndscalepd_256_mask: - case X86::BI__builtin_ia32_rndscaleps_mask: - case X86::BI__builtin_ia32_rndscalepd_mask: - case X86::BI__builtin_ia32_rndscaleph_mask: - case X86::BI__builtin_ia32_reducepd128_mask: - case X86::BI__builtin_ia32_reducepd256_mask: - case X86::BI__builtin_ia32_reducepd512_mask: - case X86::BI__builtin_ia32_reduceps128_mask: - case X86::BI__builtin_ia32_reduceps256_mask: - case X86::BI__builtin_ia32_reduceps512_mask: - case X86::BI__builtin_ia32_reduceph128_mask: - case X86::BI__builtin_ia32_reduceph256_mask: - case X86::BI__builtin_ia32_reduceph512_mask: - case X86::BI__builtin_ia32_prold512: - case X86::BI__builtin_ia32_prolq512: - case X86::BI__builtin_ia32_prold128: - case X86::BI__builtin_ia32_prold256: - case X86::BI__builtin_ia32_prolq128: - case X86::BI__builtin_ia32_prolq256: - case X86::BI__builtin_ia32_prord512: - case X86::BI__builtin_ia32_prorq512: - case X86::BI__builtin_ia32_prord128: - case X86::BI__builtin_ia32_prord256: - case X86::BI__builtin_ia32_prorq128: - case X86::BI__builtin_ia32_prorq256: - case X86::BI__builtin_ia32_fpclasspd128_mask: - case X86::BI__builtin_ia32_fpclasspd256_mask: - case X86::BI__builtin_ia32_fpclassps128_mask: - case X86::BI__builtin_ia32_fpclassps256_mask: - case X86::BI__builtin_ia32_fpclassps512_mask: - case X86::BI__builtin_ia32_fpclasspd512_mask: - case X86::BI__builtin_ia32_fpclassph128_mask: - case X86::BI__builtin_ia32_fpclassph256_mask: - case X86::BI__builtin_ia32_fpclassph512_mask: - case X86::BI__builtin_ia32_fpclasssd_mask: - case X86::BI__builtin_ia32_fpclassss_mask: - case X86::BI__builtin_ia32_fpclasssh_mask: - case X86::BI__builtin_ia32_pslldqi128_byteshift: - case X86::BI__builtin_ia32_pslldqi256_byteshift: - case X86::BI__builtin_ia32_pslldqi512_byteshift: - case X86::BI__builtin_ia32_psrldqi128_byteshift: - case X86::BI__builtin_ia32_psrldqi256_byteshift: - case X86::BI__builtin_ia32_psrldqi512_byteshift: - case X86::BI__builtin_ia32_kshiftliqi: - case X86::BI__builtin_ia32_kshiftlihi: - case X86::BI__builtin_ia32_kshiftlisi: - case X86::BI__builtin_ia32_kshiftlidi: - case X86::BI__builtin_ia32_kshiftriqi: - case X86::BI__builtin_ia32_kshiftrihi: - case X86::BI__builtin_ia32_kshiftrisi: - case X86::BI__builtin_ia32_kshiftridi: - i = 1; l = 0; u = 255; - break; - case X86::BI__builtin_ia32_vperm2f128_pd256: - case X86::BI__builtin_ia32_vperm2f128_ps256: - case X86::BI__builtin_ia32_vperm2f128_si256: - case X86::BI__builtin_ia32_permti256: - case X86::BI__builtin_ia32_pblendw128: - case X86::BI__builtin_ia32_pblendw256: - case X86::BI__builtin_ia32_blendps256: - case X86::BI__builtin_ia32_pblendd256: - case X86::BI__builtin_ia32_palignr128: - case X86::BI__builtin_ia32_palignr256: - case X86::BI__builtin_ia32_palignr512: - case X86::BI__builtin_ia32_alignq512: - case X86::BI__builtin_ia32_alignd512: - case X86::BI__builtin_ia32_alignd128: - case X86::BI__builtin_ia32_alignd256: - case X86::BI__builtin_ia32_alignq128: - case X86::BI__builtin_ia32_alignq256: - case X86::BI__builtin_ia32_vcomisd: - case X86::BI__builtin_ia32_vcomiss: - case X86::BI__builtin_ia32_shuf_f32x4: - case X86::BI__builtin_ia32_shuf_f64x2: - case X86::BI__builtin_ia32_shuf_i32x4: - case X86::BI__builtin_ia32_shuf_i64x2: - case X86::BI__builtin_ia32_shufpd512: - case X86::BI__builtin_ia32_shufps: - case X86::BI__builtin_ia32_shufps256: - case X86::BI__builtin_ia32_shufps512: - case X86::BI__builtin_ia32_dbpsadbw128: - case X86::BI__builtin_ia32_dbpsadbw256: - case X86::BI__builtin_ia32_dbpsadbw512: - case X86::BI__builtin_ia32_vpshldd128: - case X86::BI__builtin_ia32_vpshldd256: - case X86::BI__builtin_ia32_vpshldd512: - case X86::BI__builtin_ia32_vpshldq128: - case X86::BI__builtin_ia32_vpshldq256: - case X86::BI__builtin_ia32_vpshldq512: - case X86::BI__builtin_ia32_vpshldw128: - case X86::BI__builtin_ia32_vpshldw256: - case X86::BI__builtin_ia32_vpshldw512: - case X86::BI__builtin_ia32_vpshrdd128: - case X86::BI__builtin_ia32_vpshrdd256: - case X86::BI__builtin_ia32_vpshrdd512: - case X86::BI__builtin_ia32_vpshrdq128: - case X86::BI__builtin_ia32_vpshrdq256: - case X86::BI__builtin_ia32_vpshrdq512: - case X86::BI__builtin_ia32_vpshrdw128: - case X86::BI__builtin_ia32_vpshrdw256: - case X86::BI__builtin_ia32_vpshrdw512: - i = 2; l = 0; u = 255; - break; - case X86::BI__builtin_ia32_fixupimmpd512_mask: - case X86::BI__builtin_ia32_fixupimmpd512_maskz: - case X86::BI__builtin_ia32_fixupimmps512_mask: - case X86::BI__builtin_ia32_fixupimmps512_maskz: - case X86::BI__builtin_ia32_fixupimmsd_mask: - case X86::BI__builtin_ia32_fixupimmsd_maskz: - case X86::BI__builtin_ia32_fixupimmss_mask: - case X86::BI__builtin_ia32_fixupimmss_maskz: - case X86::BI__builtin_ia32_fixupimmpd128_mask: - case X86::BI__builtin_ia32_fixupimmpd128_maskz: - case X86::BI__builtin_ia32_fixupimmpd256_mask: - case X86::BI__builtin_ia32_fixupimmpd256_maskz: - case X86::BI__builtin_ia32_fixupimmps128_mask: - case X86::BI__builtin_ia32_fixupimmps128_maskz: - case X86::BI__builtin_ia32_fixupimmps256_mask: - case X86::BI__builtin_ia32_fixupimmps256_maskz: - case X86::BI__builtin_ia32_pternlogd512_mask: - case X86::BI__builtin_ia32_pternlogd512_maskz: - case X86::BI__builtin_ia32_pternlogq512_mask: - case X86::BI__builtin_ia32_pternlogq512_maskz: - case X86::BI__builtin_ia32_pternlogd128_mask: - case X86::BI__builtin_ia32_pternlogd128_maskz: - case X86::BI__builtin_ia32_pternlogd256_mask: - case X86::BI__builtin_ia32_pternlogd256_maskz: - case X86::BI__builtin_ia32_pternlogq128_mask: - case X86::BI__builtin_ia32_pternlogq128_maskz: - case X86::BI__builtin_ia32_pternlogq256_mask: - case X86::BI__builtin_ia32_pternlogq256_maskz: - case X86::BI__builtin_ia32_vsm3rnds2: - i = 3; l = 0; u = 255; - break; - case X86::BI__builtin_ia32_gatherpfdpd: - case X86::BI__builtin_ia32_gatherpfdps: - case X86::BI__builtin_ia32_gatherpfqpd: - case X86::BI__builtin_ia32_gatherpfqps: - case X86::BI__builtin_ia32_scatterpfdpd: - case X86::BI__builtin_ia32_scatterpfdps: - case X86::BI__builtin_ia32_scatterpfqpd: - case X86::BI__builtin_ia32_scatterpfqps: - i = 4; l = 2; u = 3; - break; - case X86::BI__builtin_ia32_reducesd_mask: - case X86::BI__builtin_ia32_reducess_mask: - case X86::BI__builtin_ia32_rndscalesd_round_mask: - case X86::BI__builtin_ia32_rndscaless_round_mask: - case X86::BI__builtin_ia32_rndscalesh_round_mask: - case X86::BI__builtin_ia32_reducesh_mask: - i = 4; l = 0; u = 255; - break; - case X86::BI__builtin_ia32_cmpccxadd32: - case X86::BI__builtin_ia32_cmpccxadd64: - i = 3; l = 0; u = 15; - break; - } - - // Note that we don't force a hard error on the range check here, allowing - // template-generated or macro-generated dead code to potentially have out-of- - // range values. These need to code generate, but don't need to necessarily - // make any sense. We use a warning that defaults to an error. - return BuiltinConstantArgRange(TheCall, i, l, u, /*RangeIsError*/ false); -} - /// Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo /// parameter with the FormatAttr's correct format_idx and firstDataArg. /// Returns true when the format fits the function and the FormatStringInfo has @@ -8521,7 +6803,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, const PointerType *pointerType = Ptr->getType()->getAs(); if (!pointerType) { Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer) - << Ptr->getType() << Ptr->getSourceRange(); + << Ptr->getType() << 0 << Ptr->getSourceRange(); return ExprError(); } @@ -8550,6 +6832,13 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, } } + // Pointer to object of size zero is not allowed. + if (Context.getTypeInfoInChars(AtomTy).Width.isZero()) { + Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer) + << Ptr->getType() << 1 << Ptr->getSourceRange(); + return ExprError(); + } + // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { // GCC does not enforce these rules for GNU atomics, but we do to help catch @@ -8941,7 +7230,7 @@ ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) { const PointerType *pointerType = FirstArg->getType()->getAs(); if (!pointerType) { Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) - << FirstArg->getType() << FirstArg->getSourceRange(); + << FirstArg->getType() << 0 << FirstArg->getSourceRange(); return ExprError(); } @@ -8949,7 +7238,7 @@ ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) { if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && !ValType->isBlockPointerType()) { Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr) - << FirstArg->getType() << FirstArg->getSourceRange(); + << FirstArg->getType() << 0 << FirstArg->getSourceRange(); return ExprError(); } @@ -9302,7 +7591,7 @@ ExprResult Sema::BuiltinNontemporalOverloaded(ExprResult TheCallResult) { unsigned numArgs = isStore ? 2 : 1; // Ensure that we have the proper number of arguments. - if (checkArgCount(*this, TheCall, numArgs)) + if (checkArgCount(TheCall, numArgs)) return ExprError(); // Inspect the last argument of the nontemporal builtin. This should always @@ -9467,7 +7756,7 @@ bool Sema::BuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) { // In C23 mode, va_start only needs one argument. However, the builtin still // requires two arguments (which matches the behavior of the GCC builtin), // passes `0` as the second argument in C23 mode. - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; // Type-check the first argument normally. @@ -9598,7 +7887,7 @@ bool Sema::BuiltinVAStartARMMicrosoft(CallExpr *Call) { /// BuiltinUnorderedCompare - Handle functions like __builtin_isgreater and /// friends. This is declared to take (...), so we have to check everything. bool Sema::BuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; if (BuiltinID == Builtin::BI__builtin_isunordered && @@ -9642,7 +7931,7 @@ bool Sema::BuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { /// to check everything. bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, unsigned BuiltinID) { - if (checkArgCount(*this, TheCall, NumArgs)) + if (checkArgCount(TheCall, NumArgs)) return true; FPOptions FPO = TheCall->getFPFeaturesInEffect(getLangOpts()); @@ -9727,7 +8016,7 @@ bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, /// Perform semantic analysis for a call to __builtin_complex. bool Sema::BuiltinComplex(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; bool Dependent = false; @@ -9789,7 +8078,7 @@ bool Sema::BuiltinComplex(CallExpr *TheCall) { // vector short vec_xxsldwi(vector short, vector short, int); bool Sema::BuiltinVSX(CallExpr *TheCall) { unsigned ExpectedNumArgs = 3; - if (checkArgCount(*this, TheCall, ExpectedNumArgs)) + if (checkArgCount(TheCall, ExpectedNumArgs)) return true; // Check the third argument is a compile time constant @@ -9976,7 +8265,7 @@ bool Sema::BuiltinArithmeticFence(CallExpr *TheCall) { if (!Context.getTargetInfo().checkArithmeticFenceSupported()) return Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; Expr *Arg = TheCall->getArg(0); if (Arg->isInstantiationDependent()) @@ -10046,7 +8335,7 @@ bool Sema::BuiltinAllocaWithAlign(CallExpr *TheCall) { /// Handle __builtin_assume_aligned. This is declared /// as (const void*, size_t, ...) and can take one optional constant int arg. bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) { - if (checkArgCountRange(*this, TheCall, 2, 3)) + if (checkArgCountRange(TheCall, 2, 3)) return true; unsigned NumArgs = TheCall->getNumArgs(); @@ -10349,7 +8638,7 @@ bool Sema::BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, /// BuiltinARMMemoryTaggingCall - Handle calls of memory tagging extensions bool Sema::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == AArch64::BI__builtin_arm_irg) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; Expr *Arg0 = TheCall->getArg(0); Expr *Arg1 = TheCall->getArg(1); @@ -10377,7 +8666,7 @@ bool Sema::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall) { } if (BuiltinID == AArch64::BI__builtin_arm_addg) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; Expr *Arg0 = TheCall->getArg(0); @@ -10398,7 +8687,7 @@ bool Sema::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall) { } if (BuiltinID == AArch64::BI__builtin_arm_gmi) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; Expr *Arg0 = TheCall->getArg(0); Expr *Arg1 = TheCall->getArg(1); @@ -10421,7 +8710,7 @@ bool Sema::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == AArch64::BI__builtin_arm_ldg || BuiltinID == AArch64::BI__builtin_arm_stg) { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; Expr *Arg0 = TheCall->getArg(0); ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0); @@ -10694,7 +8983,7 @@ bool Sema::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, (void) DecodePPCMMATypeFromStr(Context, TypeStr, Mask); ArgNum++; } - if (checkArgCount(*this, TheCall, ArgNum)) + if (checkArgCount(TheCall, ArgNum)) return true; return false; @@ -19706,7 +17995,7 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) { } bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; ExprResult A = UsualUnaryConversions(TheCall->getArg(0)); @@ -19745,7 +18034,7 @@ bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) { } bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; ExprResult A = TheCall->getArg(0); @@ -19774,7 +18063,7 @@ bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res) { bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall, bool CheckForFloatArgs) { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return true; Expr *Args[3]; @@ -19817,7 +18106,7 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall, } bool Sema::PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; ExprResult A = UsualUnaryConversions(TheCall->getArg(0)); @@ -19829,7 +18118,7 @@ bool Sema::PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall) { } bool Sema::BuiltinNonDeterministicValue(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; ExprResult Arg = TheCall->getArg(0); @@ -19845,7 +18134,7 @@ bool Sema::BuiltinNonDeterministicValue(CallExpr *TheCall) { ExprResult Sema::BuiltinMatrixTranspose(CallExpr *TheCall, ExprResult CallResult) { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return ExprError(); ExprResult MatrixArg = DefaultLvalueConversion(TheCall->getArg(0)); @@ -19900,7 +18189,7 @@ ExprResult Sema::BuiltinMatrixColumnMajorLoad(CallExpr *TheCall, return ExprError(); } - if (checkArgCount(*this, TheCall, 4)) + if (checkArgCount(TheCall, 4)) return ExprError(); unsigned PtrArgIdx = 0; @@ -20011,7 +18300,7 @@ ExprResult Sema::BuiltinMatrixColumnMajorLoad(CallExpr *TheCall, ExprResult Sema::BuiltinMatrixColumnMajorStore(CallExpr *TheCall, ExprResult CallResult) { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return ExprError(); unsigned PtrArgIdx = 1; @@ -20137,7 +18426,7 @@ static bool CheckWasmBuiltinArgIsInteger(Sema &S, CallExpr *E, /// Check that the first argument is a WebAssembly table, and the second /// is an index to use as index into the table. bool Sema::BuiltinWasmTableGet(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 2)) + if (checkArgCount(TheCall, 2)) return true; QualType ElTy; @@ -20160,7 +18449,7 @@ bool Sema::BuiltinWasmTableGet(CallExpr *TheCall) { /// an index to use as index into the table and the third is the reference /// type to set into the table. bool Sema::BuiltinWasmTableSet(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return true; QualType ElTy; @@ -20178,7 +18467,7 @@ bool Sema::BuiltinWasmTableSet(CallExpr *TheCall) { /// Check that the argument is a WebAssembly table. bool Sema::BuiltinWasmTableSize(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 1)) + if (checkArgCount(TheCall, 1)) return true; QualType ElTy; @@ -20192,7 +18481,7 @@ bool Sema::BuiltinWasmTableSize(CallExpr *TheCall) { /// value to use for new elements (of a type matching the table type), the /// third value is an integer. bool Sema::BuiltinWasmTableGrow(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 3)) + if (checkArgCount(TheCall, 3)) return true; QualType ElTy; @@ -20216,7 +18505,7 @@ bool Sema::BuiltinWasmTableGrow(CallExpr *TheCall) { /// integer, the third is the value to use to fill the table (of a type /// matching the table type), and the fourth is an integer. bool Sema::BuiltinWasmTableFill(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 4)) + if (checkArgCount(TheCall, 4)) return true; QualType ElTy; @@ -20243,7 +18532,7 @@ bool Sema::BuiltinWasmTableFill(CallExpr *TheCall) { /// WebAssembly table (of the same element type), and the third to fifth /// arguments are integers. bool Sema::BuiltinWasmTableCopy(CallExpr *TheCall) { - if (checkArgCount(*this, TheCall, 5)) + if (checkArgCount(TheCall, 5)) return true; QualType XElTy; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index ad3ca4cc94ca6..cd1c5f9391ccd 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -5692,8 +5692,15 @@ QualType getApproximateType(const Expr *E) { } } if (const auto *UO = llvm::dyn_cast(E)) { - if (UO->getOpcode() == UnaryOperatorKind::UO_Deref) - return UO->getSubExpr()->getType()->getPointeeType(); + if (UO->getOpcode() == UnaryOperatorKind::UO_Deref) { + // We recurse into the subexpression because it could be of dependent + // type. + if (auto Pointee = getApproximateType(UO->getSubExpr())->getPointeeType(); + !Pointee.isNull()) + return Pointee; + // Our caller expects a non-null result, even though the SubType is + // supposed to have a pointee. Fall through to Unresolved anyway. + } } return Unresolved; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6764a979168d6..2a87b26f17a2b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -50,6 +50,7 @@ #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" +#include "clang/Sema/SemaRISCV.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" @@ -4985,7 +4986,7 @@ void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, if (TagFromDeclSpec->hasNameForLinkage()) return; - // A well-formed anonymous tag must always be a TUK_Definition. + // A well-formed anonymous tag must always be a TagUseKind::Definition. assert(TagFromDeclSpec->isThisDeclarationADefinition()); // The type must match the tag exactly; no qualifiers allowed. @@ -8926,8 +8927,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { const FunctionDecl *FD = cast(CurContext); llvm::StringMap CallerFeatureMap; Context.getFunctionFeatureMap(CallerFeatureMap, FD); - checkRVVTypeSupport(T, NewVD->getLocation(), cast(CurContext), - CallerFeatureMap); + RISCV().checkRVVTypeSupport(T, NewVD->getLocation(), cast(CurContext), + CallerFeatureMap); } } @@ -11867,8 +11868,8 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, return false; if (!OldDecl || !OldDecl->getAsFunction() || - OldDecl->getDeclContext()->getRedeclContext() != - NewFD->getDeclContext()->getRedeclContext()) { + !OldDecl->getDeclContext()->getRedeclContext()->Equals( + NewFD->getDeclContext()->getRedeclContext())) { // If there's no previous declaration, AND this isn't attempting to cause // multiversioning, this isn't an error condition. if (MVKind == MultiVersionKind::None) @@ -17238,9 +17239,9 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, OffsetOfKind OOK, SkipBodyInfo *SkipBody) { // If this is not a definition, it must have a name. IdentifierInfo *OrigName = Name; - assert((Name != nullptr || TUK == TUK_Definition) && + assert((Name != nullptr || TUK == TagUseKind::Definition) && "Nameless record must be a definition!"); - assert(TemplateParameterLists.size() == 0 || TUK != TUK_Reference); + assert(TemplateParameterLists.size() == 0 || TUK != TagUseKind::Reference); OwnedDecl = false; TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); @@ -17254,11 +17255,11 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // or a scope specifier, which also conveniently avoids this work // for non-C++ cases. if (TemplateParameterLists.size() > 0 || - (SS.isNotEmpty() && TUK != TUK_Reference)) { + (SS.isNotEmpty() && TUK != TagUseKind::Reference)) { TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( KWLoc, NameLoc, SS, nullptr, TemplateParameterLists, - TUK == TUK_Friend, isMemberSpecialization, Invalid); + TUK == TagUseKind::Friend, isMemberSpecialization, Invalid); // C++23 [dcl.type.elab] p2: // If an elaborated-type-specifier is the sole constituent of a @@ -17273,7 +17274,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // FIXME: Class template partial specializations can be forward declared // per CWG2213, but the resolution failed to allow qualified forward // declarations. This is almost certainly unintentional, so we allow them. - if (TUK == TUK_Declaration && SS.isNotEmpty() && !isMemberSpecialization) + if (TUK == TagUseKind::Declaration && SS.isNotEmpty() && + !isMemberSpecialization) Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier) << TypeWithKeyword::getTagTypeKindName(Kind) << SS.getRange(); @@ -17310,7 +17312,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, return true; } - if (TUK == TUK_Friend && Kind == TagTypeKind::Enum) { + if (TUK == TagUseKind::Friend && Kind == TagTypeKind::Enum) { // C++23 [dcl.type.elab]p4: // If an elaborated-type-specifier appears with the friend specifier as // an entire member-declaration, the member-declaration shall have one @@ -17361,7 +17363,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // of 'int'. However, if this is an unfixed forward declaration, don't set // the underlying type unless the user enables -fms-compatibility. This // makes unfixed forward declared enums incomplete and is more conforming. - if (TUK == TUK_Definition || getLangOpts().MSVCCompat) + if (TUK == TagUseKind::Definition || getLangOpts().MSVCCompat) EnumUnderlying = Context.IntTy.getTypePtr(); } } @@ -17372,7 +17374,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, bool isStdAlignValT = false; RedeclarationKind Redecl = forRedeclarationInCurContext(); - if (TUK == TUK_Friend || TUK == TUK_Reference) + if (TUK == TagUseKind::Friend || TUK == TagUseKind::Reference) Redecl = RedeclarationKind::NotForRedeclaration; /// Create a new tag decl in C/ObjC. Since the ODR-like semantics for ObjC/C @@ -17390,7 +17392,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, New = EnumDecl::Create(Context, SearchDC, KWLoc, Loc, Name, nullptr, ScopedEnum, ScopedEnumUsesClassTag, IsFixed); // If this is an undefined enum, bail. - if (TUK != TUK_Definition && !Invalid) + if (TUK != TagUseKind::Definition && !Invalid) return nullptr; if (EnumUnderlying) { EnumDecl *ED = cast(New); @@ -17418,7 +17420,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // many points during the parsing of a struct declaration (because // the #pragma tokens are effectively skipped over during the // parsing of the struct). - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) { + if (TUK == TagUseKind::Definition && + (!SkipBody || !SkipBody->ShouldSkip)) { AddAlignmentAttributesForRecord(RD); AddMsStructLayoutForRecord(RD); } @@ -17439,7 +17442,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // If this is a friend or a reference to a class in a dependent // context, don't try to make a decl for it. - if (TUK == TUK_Friend || TUK == TUK_Reference) { + if (TUK == TagUseKind::Friend || TUK == TagUseKind::Reference) { DC = computeDeclContext(SS, false); if (!DC) { IsDependent = true; @@ -17472,7 +17475,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // this as a dependent elaborated-type-specifier. // But this only makes any sense for reference-like lookups. if (Previous.wasNotFoundInCurrentInstantiation() && - (TUK == TUK_Reference || TUK == TUK_Friend)) { + (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend)) { IsDependent = true; return true; } @@ -17489,7 +17492,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // If T is the name of a class, then each of the following shall have a // name different from T: // -- every member of class T that is itself a type - if (TUK != TUK_Reference && TUK != TUK_Friend && + if (TUK != TagUseKind::Reference && TUK != TagUseKind::Friend && DiagnoseClassNameShadow(SearchDC, DeclarationNameInfo(Name, NameLoc))) return true; @@ -17503,7 +17506,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // When declaring or defining a tag, ignore ambiguities introduced // by types using'ed into this scope. if (Previous.isAmbiguous() && - (TUK == TUK_Definition || TUK == TUK_Declaration)) { + (TUK == TagUseKind::Definition || TUK == TagUseKind::Declaration)) { LookupResult::Filter F = Previous.makeFilter(); while (F.hasNext()) { NamedDecl *ND = F.next(); @@ -17527,7 +17530,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // // Does it matter that this should be by scope instead of by // semantic context? - if (!Previous.empty() && TUK == TUK_Friend) { + if (!Previous.empty() && TUK == TagUseKind::Friend) { DeclContext *EnclosingNS = SearchDC->getEnclosingNamespaceContext(); LookupResult::Filter F = Previous.makeFilter(); bool FriendSawTagOutsideEnclosingNamespace = false; @@ -17557,7 +17560,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (Previous.isAmbiguous()) return true; - if (!getLangOpts().CPlusPlus && TUK != TUK_Reference) { + if (!getLangOpts().CPlusPlus && TUK != TagUseKind::Reference) { // FIXME: This makes sure that we ignore the contexts associated // with C structs, unions, and enums when looking for a matching // tag declaration or definition. See the similar lookup tweak @@ -17609,11 +17612,12 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // also need to do a redeclaration lookup there, just in case // there's a shadow friend decl. if (Name && Previous.empty() && - (TUK == TUK_Reference || TUK == TUK_Friend || IsTemplateParamOrArg)) { + (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend || + IsTemplateParamOrArg)) { if (Invalid) goto CreateNewDecl; assert(SS.isEmpty()); - if (TUK == TUK_Reference || IsTemplateParamOrArg) { + if (TUK == TagUseKind::Reference || IsTemplateParamOrArg) { // C++ [basic.scope.pdecl]p5: // -- for an elaborated-type-specifier of the form // @@ -17647,7 +17651,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // Find the scope where we'll be declaring the tag. S = getTagInjectionScope(S, getLangOpts()); } else { - assert(TUK == TUK_Friend); + assert(TUK == TagUseKind::Friend); CXXRecordDecl *RD = dyn_cast(SearchDC); // C++ [namespace.memdef]p3: @@ -17712,7 +17716,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // redefinition if either context is within the other. if (auto *Shadow = dyn_cast(DirectPrevDecl)) { auto *OldTag = dyn_cast(PrevDecl); - if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend && + if (SS.isEmpty() && TUK != TagUseKind::Reference && + TUK != TagUseKind::Friend && isDeclInScope(Shadow, SearchDC, S, isMemberSpecialization) && !(OldTag && isAcceptableTagRedeclContext( *this, OldTag->getDeclContext(), SearchDC))) { @@ -17731,13 +17736,13 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // If this is a use of a previous tag, or if the tag is already declared // in the same scope (so that the definition/declaration completes or // rementions the tag), reuse the decl. - if (TUK == TUK_Reference || TUK == TUK_Friend || + if (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend || isDeclInScope(DirectPrevDecl, SearchDC, S, SS.isNotEmpty() || isMemberSpecialization)) { // Make sure that this wasn't declared as an enum and now used as a // struct or something similar. if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, - TUK == TUK_Definition, KWLoc, + TUK == TagUseKind::Definition, KWLoc, Name)) { bool SafeToContinue = (PrevTagDecl->getTagKind() != TagTypeKind::Enum && @@ -17764,7 +17769,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (Kind == TagTypeKind::Enum && PrevTagDecl->getTagKind() == TagTypeKind::Enum) { const EnumDecl *PrevEnum = cast(PrevTagDecl); - if (TUK == TUK_Reference || TUK == TUK_Friend) + if (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend) return PrevTagDecl; QualType EnumUnderlyingTy; @@ -17779,14 +17784,14 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc, ScopedEnum, EnumUnderlyingTy, IsFixed, PrevEnum)) - return TUK == TUK_Declaration ? PrevTagDecl : nullptr; + return TUK == TagUseKind::Declaration ? PrevTagDecl : nullptr; } // C++11 [class.mem]p1: // A member shall not be declared twice in the member-specification, // except that a nested class or member class template can be declared // and then later defined. - if (TUK == TUK_Declaration && PrevDecl->isCXXClassMember() && + if (TUK == TagUseKind::Declaration && PrevDecl->isCXXClassMember() && S->isDeclScope(PrevDecl)) { Diag(NameLoc, diag::ext_member_redeclared); Diag(PrevTagDecl->getLocation(), diag::note_previous_declaration); @@ -17795,11 +17800,11 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (!Invalid) { // If this is a use, just return the declaration we found, unless // we have attributes. - if (TUK == TUK_Reference || TUK == TUK_Friend) { + if (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend) { if (!Attrs.empty()) { // FIXME: Diagnose these attributes. For now, we create a new // declaration to hold them. - } else if (TUK == TUK_Reference && + } else if (TUK == TagUseKind::Reference && (PrevTagDecl->getFriendObjectKind() == Decl::FOK_Undeclared || PrevDecl->getOwningModule() != getCurrentModule()) && @@ -17823,7 +17828,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, } // Diagnose attempts to redefine a tag. - if (TUK == TUK_Definition) { + if (TUK == TagUseKind::Definition) { if (NamedDecl *Def = PrevTagDecl->getDefinition()) { // If we're defining a specialization and the previous definition // is from an implicit instantiation, don't emit an error @@ -17903,7 +17908,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // Okay, we're going to make a redeclaration. If this is some kind // of reference, make sure we build the redeclaration in the same DC // as the original, and ignore the current access specifier. - if (TUK == TUK_Friend || TUK == TUK_Reference) { + if (TUK == TagUseKind::Friend || TUK == TagUseKind::Reference) { SearchDC = PrevTagDecl->getDeclContext(); AS = AS_none; } @@ -17929,7 +17934,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // Use a better diagnostic if an elaborated-type-specifier // found the wrong kind of type on the first // (non-redeclaration) lookup. - if ((TUK == TUK_Reference || TUK == TUK_Friend) && + if ((TUK == TagUseKind::Reference || TUK == TagUseKind::Friend) && !Previous.isForRedeclaration()) { NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl, Kind); Diag(NameLoc, diag::err_tag_reference_non_tag) @@ -17943,7 +17948,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // do nothing // Diagnose implicit declarations introduced by elaborated types. - } else if (TUK == TUK_Reference || TUK == TUK_Friend) { + } else if (TUK == TagUseKind::Reference || TUK == TagUseKind::Friend) { NonTagKind NTK = getNonTagTypeDeclKind(PrevDecl, Kind); Diag(NameLoc, diag::err_tag_reference_conflict) << NTK; Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl; @@ -18002,7 +18007,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, StdAlignValT = cast(New); // If this is an undefined enum, warn. - if (TUK != TUK_Definition && !Invalid) { + if (TUK != TagUseKind::Definition && !Invalid) { TagDecl *Def; if (IsFixed && cast(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. @@ -18052,21 +18057,22 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, } // Only C23 and later allow defining new types in 'offsetof()'. - if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus && - !getLangOpts().C23) + if (OOK != OOK_Outside && TUK == TagUseKind::Definition && + !getLangOpts().CPlusPlus && !getLangOpts().C23) Diag(New->getLocation(), diag::ext_type_defined_in_offsetof) << (OOK == OOK_Macro) << New->getSourceRange(); // C++11 [dcl.type]p3: // A type-specifier-seq shall not define a class or enumeration [...]. if (!Invalid && getLangOpts().CPlusPlus && - (IsTypeSpecifier || IsTemplateParamOrArg) && TUK == TUK_Definition) { + (IsTypeSpecifier || IsTemplateParamOrArg) && + TUK == TagUseKind::Definition) { Diag(New->getLocation(), diag::err_type_defined_in_type_specifier) << Context.getTagDeclType(New); Invalid = true; } - if (!Invalid && getLangOpts().CPlusPlus && TUK == TUK_Definition && + if (!Invalid && getLangOpts().CPlusPlus && TUK == TagUseKind::Definition && DC->getDeclKind() == Decl::Enum) { Diag(New->getLocation(), diag::err_type_defined_in_enum) << Context.getTagDeclType(New); @@ -18078,7 +18084,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (SS.isSet()) { // If this is either a declaration or a definition, check the // nested-name-specifier against the current context. - if ((TUK == TUK_Definition || TUK == TUK_Declaration) && + if ((TUK == TagUseKind::Definition || TUK == TagUseKind::Declaration) && diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc, /*TemplateId=*/nullptr, isMemberSpecialization)) @@ -18103,7 +18109,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // many points during the parsing of a struct declaration (because // the #pragma tokens are effectively skipped over during the // parsing of the struct). - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) { + if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip)) { AddAlignmentAttributesForRecord(RD); AddMsStructLayoutForRecord(RD); } @@ -18134,7 +18140,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (getLangOpts().CPlusPlus) { // C++ [dcl.fct]p6: // Types shall not be defined in return or parameter types. - if (TUK == TUK_Definition && !IsTypeSpecifier) { + if (TUK == TagUseKind::Definition && !IsTypeSpecifier) { Diag(Loc, diag::err_type_defined_in_param_type) << Name; Invalid = true; @@ -18155,7 +18161,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, // In Microsoft mode, a friend declaration also acts as a forward // declaration so we always pass true to setObjectOfFriendDecl to make // the tag name visible. - if (TUK == TUK_Friend) + if (TUK == TagUseKind::Friend) New->setObjectOfFriendDecl(getLangOpts().MSVCCompat); // Set the access specifier. @@ -18165,14 +18171,14 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, if (PrevDecl) CheckRedeclarationInModule(New, PrevDecl); - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) + if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip)) New->startDefinition(); ProcessDeclAttributeList(S, New, Attrs); AddPragmaAttributes(S, New); // If this has an identifier, add it to the scope stack. - if (TUK == TUK_Friend) { + if (TUK == TagUseKind::Friend) { // We might be replacing an existing declaration in the lookup tables; // if so, borrow its access specifier. if (PrevDecl) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ca5938083917f..5041fd65286fa 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -8663,31 +8663,95 @@ static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) { return RD; } -static bool -CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E, - llvm::SmallVectorImpl &Decls) { +enum class CountedByInvalidPointeeTypeKind { + INCOMPLETE, + SIZELESS, + FUNCTION, + FLEXIBLE_ARRAY_MEMBER, + VALID, +}; + +static bool CheckCountedByAttrOnField( + Sema &S, FieldDecl *FD, Expr *E, + llvm::SmallVectorImpl &Decls) { + // Check the context the attribute is used in + if (FD->getParent()->isUnion()) { S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_in_union) << FD->getSourceRange(); return true; } - if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) { - S.Diag(E->getBeginLoc(), diag::err_counted_by_attr_argument_not_integer) - << E->getSourceRange(); + const auto FieldTy = FD->getType(); + if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) { + S.Diag(FD->getBeginLoc(), + diag::err_counted_by_attr_not_on_ptr_or_flexible_array_member) + << FD->getLocation(); return true; } LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = LangOptions::StrictFlexArraysLevelKind::IncompleteOnly; - - if (!Decl::isFlexibleArrayMemberLike(S.getASTContext(), FD, FD->getType(), + if (FieldTy->isArrayType() && + !Decl::isFlexibleArrayMemberLike(S.getASTContext(), FD, FieldTy, StrictFlexArraysLevel, true)) { - // The "counted_by" attribute must be on a flexible array member. - SourceRange SR = FD->getLocation(); - S.Diag(SR.getBegin(), - diag::err_counted_by_attr_not_on_flexible_array_member) - << SR; + S.Diag(FD->getBeginLoc(), + diag::err_counted_by_attr_on_array_not_flexible_array_member) + << FD->getLocation(); + return true; + } + + CountedByInvalidPointeeTypeKind InvalidTypeKind = + CountedByInvalidPointeeTypeKind::VALID; + QualType PointeeTy; + int SelectPtrOrArr = 0; + if (FieldTy->isPointerType()) { + PointeeTy = FieldTy->getPointeeType(); + SelectPtrOrArr = 0; + } else { + assert(FieldTy->isArrayType()); + const ArrayType *AT = S.getASTContext().getAsArrayType(FieldTy); + PointeeTy = AT->getElementType(); + SelectPtrOrArr = 1; + } + // Note: The `Decl::isFlexibleArrayMemberLike` check earlier on means + // only `PointeeTy->isStructureTypeWithFlexibleArrayMember()` is reachable + // when `FieldTy->isArrayType()`. + bool ShouldWarn = false; + if (PointeeTy->isIncompleteType()) { + InvalidTypeKind = CountedByInvalidPointeeTypeKind::INCOMPLETE; + } else if (PointeeTy->isSizelessType()) { + InvalidTypeKind = CountedByInvalidPointeeTypeKind::SIZELESS; + } else if (PointeeTy->isFunctionType()) { + InvalidTypeKind = CountedByInvalidPointeeTypeKind::FUNCTION; + } else if (PointeeTy->isStructureTypeWithFlexibleArrayMember()) { + if (FieldTy->isArrayType()) { + // This is a workaround for the Linux kernel that has already adopted + // `counted_by` on a FAM where the pointee is a struct with a FAM. This + // should be an error because computing the bounds of the array cannot be + // done correctly without manually traversing every struct object in the + // array at runtime. To allow the code to be built this error is + // downgraded to a warning. + ShouldWarn = true; + } + InvalidTypeKind = CountedByInvalidPointeeTypeKind::FLEXIBLE_ARRAY_MEMBER; + } + + if (InvalidTypeKind != CountedByInvalidPointeeTypeKind::VALID) { + unsigned DiagID = ShouldWarn + ? diag::warn_counted_by_attr_elt_type_unknown_size + : diag::err_counted_by_attr_pointee_unknown_size; + S.Diag(FD->getBeginLoc(), DiagID) + << SelectPtrOrArr << PointeeTy << (int)InvalidTypeKind + << (ShouldWarn ? 1 : 0) << FD->getSourceRange(); + return true; + } + + // Check the expression + + if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) { + S.Diag(E->getBeginLoc(), diag::err_counted_by_attr_argument_not_integer) + << E->getSourceRange(); return true; } @@ -8750,10 +8814,11 @@ static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) { return; llvm::SmallVector Decls; - if (CheckCountExpr(S, FD, CountExpr, Decls)) + if (CheckCountedByAttrOnField(S, FD, CountExpr, Decls)) return; - QualType CAT = S.BuildCountAttributedArrayType(FD->getType(), CountExpr); + QualType CAT = + S.BuildCountAttributedArrayOrPointerType(FD->getType(), CountExpr); FD->setType(CAT); } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 104e27139fe47..8ab429e2a136e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -17580,11 +17580,12 @@ DeclResult Sema::ActOnTemplatedFriendTag( if (Invalid) return true; - return CheckClassTemplate(S, TagSpec, TUK_Friend, TagLoc, SS, Name, - NameLoc, Attr, TemplateParams, AS_public, + return CheckClassTemplate(S, TagSpec, TagUseKind::Friend, TagLoc, SS, + Name, NameLoc, Attr, TemplateParams, AS_public, /*ModulePrivateLoc=*/SourceLocation(), FriendLoc, TempParamLists.size() - 1, - TempParamLists.data()).get(); + TempParamLists.data()) + .get(); } else { // The "template<>" header is extraneous. Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams) @@ -17612,8 +17613,8 @@ DeclResult Sema::ActOnTemplatedFriendTag( if (SS.isEmpty()) { bool Owned = false; bool IsDependent = false; - return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr, - AS_public, + return ActOnTag(S, TagSpec, TagUseKind::Friend, TagLoc, SS, Name, NameLoc, + Attr, AS_public, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, IsDependent, /*ScopedEnumKWLoc=*/SourceLocation(), @@ -17728,7 +17729,7 @@ Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, // Try to convert the decl specifier to a type. This works for // friend templates because ActOnTag never produces a ClassTemplateDecl - // for a TUK_Friend. + // for a TagUseKind::Friend. Declarator TheDeclarator(DS, ParsedAttributesView::none(), DeclaratorContext::Member); TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e7731e389c1ba..ded4f59833ac0 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -54,6 +54,7 @@ #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenMP.h" +#include "clang/Sema/SemaPseudoObject.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLForwardCompat.h" @@ -5184,7 +5185,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, } // Perform default conversions. - if (!LHSExp->getType()->getAs()) { + if (!LHSExp->getType()->isSubscriptableVectorType()) { ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp); if (Result.isInvalid()) return ExprError(); @@ -5240,36 +5241,22 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, << ResultType << BaseExpr->getSourceRange(); return ExprError(); } - } else if (const VectorType *VTy = LHSTy->getAs()) { - BaseExpr = LHSExp; // vectors: V[123] - IndexExpr = RHSExp; - // We apply C++ DR1213 to vector subscripting too. - if (getLangOpts().CPlusPlus11 && LHSExp->isPRValue()) { - ExprResult Materialized = TemporaryMaterializationConversion(LHSExp); - if (Materialized.isInvalid()) - return ExprError(); - LHSExp = Materialized.get(); + } else if (LHSTy->isSubscriptableVectorType()) { + if (LHSTy->isBuiltinType() && + LHSTy->getAs()->isSveVLSBuiltinType()) { + const BuiltinType *BTy = LHSTy->getAs(); + if (BTy->isSVEBool()) + return ExprError(Diag(LLoc, diag::err_subscript_svbool_t) + << LHSExp->getSourceRange() + << RHSExp->getSourceRange()); + ResultType = BTy->getSveEltType(Context); + } else { + const VectorType *VTy = LHSTy->getAs(); + ResultType = VTy->getElementType(); } - VK = LHSExp->getValueKind(); - if (VK != VK_PRValue) - OK = OK_VectorComponent; - - ResultType = VTy->getElementType(); - QualType BaseType = BaseExpr->getType(); - Qualifiers BaseQuals = BaseType.getQualifiers(); - Qualifiers MemberQuals = ResultType.getQualifiers(); - Qualifiers Combined = BaseQuals + MemberQuals; - if (Combined != MemberQuals) - ResultType = Context.getQualifiedType(ResultType, Combined); - } else if (LHSTy->isBuiltinType() && - LHSTy->getAs()->isSveVLSBuiltinType()) { - const BuiltinType *BTy = LHSTy->getAs(); - if (BTy->isSVEBool()) - return ExprError(Diag(LLoc, diag::err_subscript_svbool_t) - << LHSExp->getSourceRange() << RHSExp->getSourceRange()); - - BaseExpr = LHSExp; + BaseExpr = LHSExp; // vectors: V[123] IndexExpr = RHSExp; + // We apply C++ DR1213 to vector subscripting too. if (getLangOpts().CPlusPlus11 && LHSExp->isPRValue()) { ExprResult Materialized = TemporaryMaterializationConversion(LHSExp); if (Materialized.isInvalid()) @@ -5280,8 +5267,6 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, if (VK != VK_PRValue) OK = OK_VectorComponent; - ResultType = BTy->getSveEltType(Context); - QualType BaseType = BaseExpr->getType(); Qualifiers BaseQuals = BaseType.getQualifiers(); Qualifiers MemberQuals = ResultType.getQualifiers(); @@ -5521,6 +5506,15 @@ struct EnsureImmediateInvocationInDefaultArgs // cause it to incorrectly point it to the outermost class // in the case of nested struct initialization. ExprResult TransformCXXThisExpr(CXXThisExpr *E) { return E; } + + // Rewrite to source location to refer to the context in which they are used. + ExprResult TransformSourceLocExpr(SourceLocExpr *E) { + if (E->getParentContext() == SemaRef.CurContext) + return E; + return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(), + E->getBeginLoc(), E->getEndLoc(), + SemaRef.CurContext); + } }; ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, @@ -5578,10 +5572,9 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, Res = Immediate.TransformInitializer(Param->getInit(), /*NotCopy=*/false); }); - if (Res.isInvalid()) - return ExprError(); - Res = ConvertParamDefaultArgument(Param, Res.get(), - Res.get()->getBeginLoc()); + if (Res.isUsable()) + Res = ConvertParamDefaultArgument(Param, Res.get(), + Res.get()->getBeginLoc()); if (Res.isInvalid()) return ExprError(); Init = Res.get(); @@ -5615,9 +5608,10 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { InitializationContext.emplace(Loc, Field, CurContext); Expr *Init = nullptr; + bool HasRewrittenInit = false; bool NestedDefaultChecking = isCheckingDefaultArgumentOrInitializer(); - + bool InLifetimeExtendingContext = isInLifetimeExtendingContext(); EnterExpressionEvaluationContext EvalContext( *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field); @@ -5652,19 +5646,36 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { ImmediateCallVisitor V(getASTContext()); if (!NestedDefaultChecking) V.TraverseDecl(Field); - if (V.HasImmediateCalls) { + + // CWG1815 + // Support lifetime extension of temporary created by aggregate + // initialization using a default member initializer. We should always rebuild + // the initializer if it contains any temporaries (if the initializer + // expression is an ExprWithCleanups). Then make sure the normal lifetime + // extension code recurses into the default initializer and does lifetime + // extension when warranted. + bool ContainsAnyTemporaries = + isa_and_present(Field->getInClassInitializer()); + if (V.HasImmediateCalls || InLifetimeExtendingContext || + ContainsAnyTemporaries) { + HasRewrittenInit = true; ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field, CurContext}; ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer = NestedDefaultChecking; - + // Pass down lifetime extending flag, and collect temporaries in + // CreateMaterializeTemporaryExpr when we rewrite the call argument. + keepInLifetimeExtendingContext(); EnsureImmediateInvocationInDefaultArgs Immediate(*this); ExprResult Res; + + // Rebuild CXXDefaultInitExpr might cause diagnostics. + SFINAETrap Trap(*this); runWithSufficientStackSpace(Loc, [&] { Res = Immediate.TransformInitializer(Field->getInClassInitializer(), /*CXXDirectInit=*/false); }); - if (!Res.isInvalid()) + if (Res.isUsable()) Res = ConvertMemberDefaultInitExpression(Field, Res.get(), Loc); if (Res.isInvalid()) { Field->setInvalidDecl(); @@ -5691,7 +5702,7 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { return CXXDefaultInitExpr::Create(Context, InitializationContext->Loc, Field, InitializationContext->Context, - Init); + HasRewrittenInit ? Init : nullptr); } // DR1351: @@ -7542,27 +7553,6 @@ bool Sema::isValidSveBitcast(QualType srcTy, QualType destTy) { ValidScalableConversion(destTy, srcTy); } -/// Are the two types RVV-bitcast-compatible types? I.e. is bitcasting from the -/// first RVV type (e.g. an RVV scalable type) to the second type (e.g. an RVV -/// VLS type) allowed? -/// -/// This will also return false if the two given types do not make sense from -/// the perspective of RVV bitcasts. -bool Sema::isValidRVVBitcast(QualType srcTy, QualType destTy) { - assert(srcTy->isVectorType() || destTy->isVectorType()); - - auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) { - if (!FirstType->isRVVSizelessBuiltinType()) - return false; - - const auto *VecTy = SecondType->getAs(); - return VecTy && VecTy->getVectorKind() == VectorKind::RVVFixedLengthData; - }; - - return ValidScalableConversion(srcTy, destTy) || - ValidScalableConversion(destTy, srcTy); -} - /// Are the two types matrix types and do they have the same dimensions i.e. /// do they have the same number of rows and the same number of columns? bool Sema::areMatrixTypesOfTheSameDimension(QualType srcTy, QualType destTy) { @@ -15239,7 +15229,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, LHSExpr = LHS.get(); RHSExpr = RHS.get(); - // We want to end up calling one of checkPseudoObjectAssignment + // We want to end up calling one of SemaPseudoObject::checkAssignment // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if // both expressions are overloadable or either is type-dependent), // or CreateBuiltinBinOp (in any other case). We also want to get @@ -15250,7 +15240,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, // Assignments with a pseudo-object l-value need special analysis. if (pty->getKind() == BuiltinType::PseudoObject && BinaryOperator::isAssignmentOp(Opc)) - return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr); + return PseudoObject().checkAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr); // Don't resolve overloads if the other type is overloadable. if (getLangOpts().CPlusPlus && pty->getKind() == BuiltinType::Overload) { @@ -15673,7 +15663,7 @@ ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, // Increment and decrement of pseudo-object references. if (pty->getKind() == BuiltinType::PseudoObject && UnaryOperator::isIncrementDecrementOp(Opc)) - return checkPseudoObjectIncDec(S, OpLoc, Opc, Input); + return PseudoObject().checkIncDec(S, OpLoc, Opc, Input); // extension is always a builtin operator. if (Opc == UO_Extension) @@ -17242,8 +17232,7 @@ ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) { TypeSourceInfo *Sema::TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo) { assert(isUnevaluatedContext() && "Should only transform unevaluated expressions"); - ExprEvalContexts.back().Context = - ExprEvalContexts[ExprEvalContexts.size() - 2].Context; + ExprEvalContexts.back().Context = parentEvaluationContext().Context; if (isUnevaluatedContext()) return TInfo; return TransformToPE(*this).TransformType(TInfo); @@ -17260,14 +17249,13 @@ Sema::PushExpressionEvaluationContext( // discarded statements or immediate context are themselves // a discarded statement or an immediate context, respectively. ExprEvalContexts.back().InDiscardedStatement = - ExprEvalContexts[ExprEvalContexts.size() - 2] - .isDiscardedStatementContext(); + parentEvaluationContext().isDiscardedStatementContext(); // C++23 [expr.const]/p15 // An expression or conversion is in an immediate function context if [...] // it is a subexpression of a manifestly constant-evaluated expression or // conversion. - const auto &Prev = ExprEvalContexts[ExprEvalContexts.size() - 2]; + const auto &Prev = parentEvaluationContext(); ExprEvalContexts.back().InImmediateFunctionContext = Prev.isImmediateFunctionContext() || Prev.isConstantEvaluated(); @@ -17712,7 +17700,7 @@ void Sema::PopExpressionEvaluationContext() { // Append the collected materialized temporaries into previous context before // exit if the previous also is a lifetime extending context. - auto &PrevRecord = ExprEvalContexts[ExprEvalContexts.size() - 2]; + auto &PrevRecord = parentEvaluationContext(); if (getLangOpts().CPlusPlus23 && Rec.InLifetimeExtendingContext && PrevRecord.InLifetimeExtendingContext && !Rec.ForRangeLifetimeExtendTemps.empty()) { @@ -20890,7 +20878,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { // Pseudo-objects. case BuiltinType::PseudoObject: - return checkPseudoObjectRValue(E); + return PseudoObject().checkRValue(E); case BuiltinType::BuiltinFn: { // Accept __noop without parens by implicitly converting it to a call expr. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index f543e006060d6..d3e9dcb4f4399 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1554,9 +1554,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, bool ListInitialization) { QualType Ty = TInfo->getType(); SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); - - assert((!ListInitialization || Exprs.size() == 1) && - "List initialization must have exactly one expression."); SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc); InitializedEntity Entity = diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 353e911c5cc33..79bdc8e9f8783 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -8066,11 +8066,6 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, enum PathLifetimeKind { /// Lifetime-extend along this path. Extend, - /// We should lifetime-extend, but we don't because (due to technical - /// limitations) we can't. This happens for default member initializers, - /// which we don't clone for every use, so we don't have a unique - /// MaterializeTemporaryExpr to update. - ShouldExtend, /// Do not lifetime extend along this path. NoExtend }; @@ -8082,7 +8077,7 @@ shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) { PathLifetimeKind Kind = PathLifetimeKind::Extend; for (auto Elem : Path) { if (Elem.Kind == IndirectLocalPathEntry::DefaultInit) - Kind = PathLifetimeKind::ShouldExtend; + Kind = PathLifetimeKind::Extend; else if (Elem.Kind != IndirectLocalPathEntry::LambdaCaptureInit) return PathLifetimeKind::NoExtend; } @@ -8202,18 +8197,6 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity, ExtendingEntity->allocateManglingNumber()); // Also visit the temporaries lifetime-extended by this initializer. return true; - - case PathLifetimeKind::ShouldExtend: - // We're supposed to lifetime-extend the temporary along this path (per - // the resolution of DR1815), but we don't support that yet. - // - // FIXME: Properly handle this situation. Perhaps the easiest approach - // would be to clone the initializer expression on each use that would - // lifetime extend its temporaries. - Diag(DiagLoc, diag::warn_unsupported_lifetime_extension) - << RK << DiagRange; - break; - case PathLifetimeKind::NoExtend: // If the path goes through the initialization of a variable or field, // it can't possibly reach a temporary created in this full-expression. diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 1743afaf15287..276a43ad79b91 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -12,6 +12,7 @@ #include "clang/Sema/SemaLambda.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTLambda.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" @@ -386,30 +387,69 @@ buildTypeForLambdaCallOperator(Sema &S, clang::CXXRecordDecl *Class, // parameter, if any, of the lambda's function call operator (possibly // instantiated from a function call operator template) shall be either: // - the closure type, -// - class type derived from the closure type, or +// - class type publicly and unambiguously derived from the closure type, or // - a reference to a possibly cv-qualified such type. -void Sema::DiagnoseInvalidExplicitObjectParameterInLambda( - CXXMethodDecl *Method) { +bool Sema::DiagnoseInvalidExplicitObjectParameterInLambda( + CXXMethodDecl *Method, SourceLocation CallLoc) { if (!isLambdaCallWithExplicitObjectParameter(Method)) - return; + return false; CXXRecordDecl *RD = Method->getParent(); if (Method->getType()->isDependentType()) - return; + return false; if (RD->isCapturelessLambda()) - return; - QualType ExplicitObjectParameterType = Method->getParamDecl(0) - ->getType() + return false; + + ParmVarDecl *Param = Method->getParamDecl(0); + QualType ExplicitObjectParameterType = Param->getType() .getNonReferenceType() .getUnqualifiedType() .getDesugaredType(getASTContext()); QualType LambdaType = getASTContext().getRecordType(RD); if (LambdaType == ExplicitObjectParameterType) - return; - if (IsDerivedFrom(RD->getLocation(), ExplicitObjectParameterType, LambdaType)) - return; - Diag(Method->getParamDecl(0)->getLocation(), - diag::err_invalid_explicit_object_type_in_lambda) - << ExplicitObjectParameterType; + return false; + + // Don't check the same instantiation twice. + // + // If this call operator is ill-formed, there is no point in issuing + // a diagnostic every time it is called because the problem is in the + // definition of the derived type, not at the call site. + // + // FIXME: Move this check to where we instantiate the method? This should + // be possible, but the naive approach of just marking the method as invalid + // leads to us emitting more diagnostics than we should have to for this case + // (1 error here *and* 1 error about there being no matching overload at the + // call site). It might be possible to avoid that by also checking if there + // is an empty cast path for the method stored in the context (signalling that + // we've already diagnosed it) and then just not building the call, but that + // doesn't really seem any simpler than diagnosing it at the call site... + if (auto It = Context.LambdaCastPaths.find(Method); + It != Context.LambdaCastPaths.end()) + return It->second.empty(); + + CXXCastPath &Path = Context.LambdaCastPaths[Method]; + CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, + /*DetectVirtual=*/false); + if (!IsDerivedFrom(RD->getLocation(), ExplicitObjectParameterType, LambdaType, + Paths)) { + Diag(Param->getLocation(), diag::err_invalid_explicit_object_type_in_lambda) + << ExplicitObjectParameterType; + return true; + } + + if (Paths.isAmbiguous(LambdaType->getCanonicalTypeUnqualified())) { + std::string PathsDisplay = getAmbiguousPathsDisplayString(Paths); + Diag(CallLoc, diag::err_explicit_object_lambda_ambiguous_base) + << LambdaType << PathsDisplay; + return true; + } + + if (CheckBaseClassAccess(CallLoc, LambdaType, ExplicitObjectParameterType, + Paths.front(), + diag::err_explicit_object_lambda_inaccessible_base)) + return true; + + BuildBasePathArray(Paths, Path); + return false; } void Sema::handleLambdaNumbering( diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index e4d4cd7395ebf..ef0a655b631ab 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -34,6 +34,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaRISCV.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TypoCorrection.h" #include "llvm/ADT/STLExtras.h" @@ -945,13 +946,13 @@ bool Sema::LookupBuiltin(LookupResult &R) { } } - if (DeclareRISCVVBuiltins || DeclareRISCVSiFiveVectorBuiltins) { - if (!RVIntrinsicManager) - RVIntrinsicManager = CreateRISCVIntrinsicManager(*this); + if (RISCV().DeclareRVVBuiltins || RISCV().DeclareSiFiveVectorBuiltins) { + if (!RISCV().IntrinsicManager) + RISCV().IntrinsicManager = CreateRISCVIntrinsicManager(*this); - RVIntrinsicManager->InitIntrinsicList(); + RISCV().IntrinsicManager->InitIntrinsicList(); - if (RVIntrinsicManager->CreateIntrinsicIfFound(R, II, PP)) + if (RISCV().IntrinsicManager->CreateIntrinsicIfFound(R, II, PP)) return true; } diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index f174b2fa63c6a..09d91b31cfe5f 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -233,6 +233,19 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, return false; } + case OpenACCClauseKind::Reduction: + switch (DirectiveKind) { + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::KernelsLoop: + return true; + default: + return false; + } + default: // Do nothing so we can go to the 'unimplemented' diagnostic instead. return true; @@ -281,7 +294,6 @@ bool checkValidAfterDeviceType( return true; } } - } // namespace SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {} @@ -426,6 +438,22 @@ SemaOpenACC::ActOnClause(ArrayRef ExistingClauses, << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs << Clause.getIntExprs().size(); + // OpenACC 3.3 Section 2.5.4: + // A reduction clause may not appear on a parallel construct with a + // num_gangs clause that has more than one argument. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel && + Clause.getIntExprs().size() > 1) { + auto *Parallel = + llvm::find_if(ExistingClauses, llvm::IsaPred); + + if (Parallel != ExistingClauses.end()) { + Diag(Clause.getBeginLoc(), diag::err_acc_reduction_num_gangs_conflict) + << Clause.getIntExprs().size(); + Diag((*Parallel)->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; + } + } + // Create the AST node for the clause even if the number of expressions is // incorrect. return OpenACCNumGangsClause::Create( @@ -706,6 +734,46 @@ SemaOpenACC::ActOnClause(ArrayRef ExistingClauses, Clause.getLParenLoc(), Clause.getDeviceTypeArchitectures(), Clause.getEndLoc()); } + case OpenACCClauseKind::Reduction: { + // Restrictions only properly implemented on 'compute' constructs, and + // 'compute' constructs are the only construct that can do anything with + // this yet, so skip/treat as unimplemented in this case. + if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) + break; + + // OpenACC 3.3 Section 2.5.4: + // A reduction clause may not appear on a parallel construct with a + // num_gangs clause that has more than one argument. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) { + auto NumGangsClauses = llvm::make_filter_range( + ExistingClauses, llvm::IsaPred); + + for (auto *NGC : NumGangsClauses) { + unsigned NumExprs = + cast(NGC)->getIntExprs().size(); + + if (NumExprs > 1) { + Diag(Clause.getBeginLoc(), diag::err_acc_reduction_num_gangs_conflict) + << NumExprs; + Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; + } + } + } + + SmallVector ValidVars; + + for (Expr *Var : Clause.getVarList()) { + ExprResult Res = CheckReductionVar(Var); + + if (Res.isUsable()) + ValidVars.push_back(Res.get()); + } + + return OpenACCReductionClause::Create( + getASTContext(), Clause.getBeginLoc(), Clause.getLParenLoc(), + Clause.getReductionOp(), ValidVars, Clause.getEndLoc()); + } default: break; } @@ -715,6 +783,66 @@ SemaOpenACC::ActOnClause(ArrayRef ExistingClauses, return nullptr; } +/// OpenACC 3.3 section 2.5.15: +/// At a mininmum, the supported data types include ... the numerical data types +/// in C, C++, and Fortran. +/// +/// If the reduction var is a composite variable, each +/// member of the composite variable must be a supported datatype for the +/// reduction operation. +ExprResult SemaOpenACC::CheckReductionVar(Expr *VarExpr) { + VarExpr = VarExpr->IgnoreParenCasts(); + + auto TypeIsValid = [](QualType Ty) { + return Ty->isDependentType() || Ty->isScalarType(); + }; + + if (isa(VarExpr)) { + Expr *ASExpr = VarExpr; + QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr); + QualType EltTy = getASTContext().getBaseElementType(BaseTy); + + if (!TypeIsValid(EltTy)) { + Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) + << EltTy << /*Sub array base type*/ 1; + return ExprError(); + } + } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) { + if (!RD->isStruct() && !RD->isClass()) { + Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) + << /*not class or struct*/ 0 << VarExpr->getType(); + return ExprError(); + } + + if (!RD->isCompleteDefinition()) { + Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) + << /*incomplete*/ 1 << VarExpr->getType(); + return ExprError(); + } + if (const auto *CXXRD = dyn_cast(RD); + CXXRD && !CXXRD->isAggregate()) { + Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) + << /*aggregate*/ 2 << VarExpr->getType(); + return ExprError(); + } + + for (FieldDecl *FD : RD->fields()) { + if (!TypeIsValid(FD->getType())) { + Diag(VarExpr->getExprLoc(), + diag::err_acc_reduction_composite_member_type); + Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc); + return ExprError(); + } + } + } else if (!TypeIsValid(VarExpr->getType())) { + Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) + << VarExpr->getType() << /*Sub array base type*/ 0; + return ExprError(); + } + + return VarExpr; +} + void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc) { switch (K) { @@ -864,9 +992,7 @@ bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind, return false; } -ExprResult SemaOpenACC::ActOnVar(Expr *VarExpr) { - // We still need to retain the array subscript/subarray exprs, so work on a - // copy. +ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) { Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts(); // Sub-arrays/subscript-exprs are fine as long as the base is a @@ -882,14 +1008,19 @@ ExprResult SemaOpenACC::ActOnVar(Expr *VarExpr) { // References to a VarDecl are fine. if (const auto *DRE = dyn_cast(CurVarExpr)) { if (isa( - DRE->getDecl()->getCanonicalDecl())) + DRE->getFoundDecl()->getCanonicalDecl())) return VarExpr; } + // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a + // reduction clause must be a scalar variable name, an aggregate variable + // name, an array element, or a subarray. // A MemberExpr that references a Field is valid. - if (const auto *ME = dyn_cast(CurVarExpr)) { - if (isa(ME->getMemberDecl()->getCanonicalDecl())) - return VarExpr; + if (CK != OpenACCClauseKind::Reduction) { + if (const auto *ME = dyn_cast(CurVarExpr)) { + if (isa(ME->getMemberDecl()->getCanonicalDecl())) + return VarExpr; + } } // Referring to 'this' is always OK. @@ -898,7 +1029,9 @@ ExprResult SemaOpenACC::ActOnVar(Expr *VarExpr) { // Nothing really we can do here, as these are dependent. So just return they // are valid. - if (isa(CurVarExpr)) + if (isa(CurVarExpr) || + (CK != OpenACCClauseKind::Reduction && + isa(CurVarExpr))) return VarExpr; // There isn't really anything we can do in the case of a recovery expr, so @@ -906,7 +1039,8 @@ ExprResult SemaOpenACC::ActOnVar(Expr *VarExpr) { if (isa(CurVarExpr)) return ExprError(); - Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref); + Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref) + << (CK != OpenACCClauseKind::Reduction); return ExprError(); } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 6110e5229b076..bab61e8fd54e8 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -9815,6 +9815,25 @@ static Stmt *buildPreInits(ASTContext &Context, return nullptr; } +/// Append the \p Item or the content of a CompoundStmt to the list \p +/// TargetList. +/// +/// A CompoundStmt is used as container in case multiple statements need to be +/// stored in lieu of using an explicit list. Flattening is necessary because +/// contained DeclStmts need to be visible after the execution of the list. Used +/// for OpenMP pre-init declarations/statements. +static void appendFlattendedStmtList(SmallVectorImpl &TargetList, + Stmt *Item) { + // nullptr represents an empty list. + if (!Item) + return; + + if (auto *CS = dyn_cast(Item)) + llvm::append_range(TargetList, CS->body()); + else + TargetList.push_back(Item); +} + /// Build preinits statement for the given declarations. static Stmt * buildPreInits(ASTContext &Context, @@ -9828,6 +9847,17 @@ buildPreInits(ASTContext &Context, return nullptr; } +/// Build pre-init statement for the given statements. +static Stmt *buildPreInits(ASTContext &Context, ArrayRef PreInits) { + if (PreInits.empty()) + return nullptr; + + SmallVector Stmts; + for (Stmt *S : PreInits) + appendFlattendedStmtList(Stmts, S); + return CompoundStmt::Create(Context, PreInits, FPOptionsOverride(), {}, {}); +} + /// Build postupdate expression for the given list of postupdates expressions. static Expr *buildPostUpdate(Sema &S, ArrayRef PostUpdates) { Expr *PostUpdate = nullptr; @@ -9924,11 +9954,21 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Stmt *DependentPreInits = Transform->getPreInits(); if (!DependentPreInits) return; - for (Decl *C : cast(DependentPreInits)->getDeclGroup()) { - auto *D = cast(C); - DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), - Transform->getBeginLoc()); - Captures[Ref] = Ref; + + // Search for pre-init declared variables that need to be captured + // to be referenceable inside the directive. + SmallVector Constituents; + appendFlattendedStmtList(Constituents, DependentPreInits); + for (Stmt *S : Constituents) { + if (auto *DC = dyn_cast(S)) { + for (Decl *C : DC->decls()) { + auto *D = cast(C); + DeclRefExpr *Ref = buildDeclRefExpr( + SemaRef, D, D->getType().getNonReferenceType(), + Transform->getBeginLoc()); + Captures[Ref] = Ref; + } + } } })) return 0; @@ -15059,9 +15099,7 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeSimdDirective( bool SemaOpenMP::checkTransformableLoopNest( OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, SmallVectorImpl &LoopHelpers, - Stmt *&Body, - SmallVectorImpl, 0>> - &OriginalInits) { + Stmt *&Body, SmallVectorImpl> &OriginalInits) { OriginalInits.emplace_back(); bool Result = OMPLoopBasedDirective::doForAllLoops( AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, @@ -15095,16 +15133,70 @@ bool SemaOpenMP::checkTransformableLoopNest( DependentPreInits = Dir->getPreInits(); else llvm_unreachable("Unhandled loop transformation"); - if (!DependentPreInits) - return; - llvm::append_range(OriginalInits.back(), - cast(DependentPreInits)->getDeclGroup()); + + appendFlattendedStmtList(OriginalInits.back(), DependentPreInits); }); assert(OriginalInits.back().empty() && "No preinit after innermost loop"); OriginalInits.pop_back(); return Result; } +/// Add preinit statements that need to be propageted from the selected loop. +static void addLoopPreInits(ASTContext &Context, + OMPLoopBasedDirective::HelperExprs &LoopHelper, + Stmt *LoopStmt, ArrayRef OriginalInit, + SmallVectorImpl &PreInits) { + + // For range-based for-statements, ensure that their syntactic sugar is + // executed by adding them as pre-init statements. + if (auto *CXXRangeFor = dyn_cast(LoopStmt)) { + Stmt *RangeInit = CXXRangeFor->getInit(); + if (RangeInit) + PreInits.push_back(RangeInit); + + DeclStmt *RangeStmt = CXXRangeFor->getRangeStmt(); + PreInits.push_back(new (Context) DeclStmt(RangeStmt->getDeclGroup(), + RangeStmt->getBeginLoc(), + RangeStmt->getEndLoc())); + + DeclStmt *RangeEnd = CXXRangeFor->getEndStmt(); + PreInits.push_back(new (Context) DeclStmt(RangeEnd->getDeclGroup(), + RangeEnd->getBeginLoc(), + RangeEnd->getEndLoc())); + } + + llvm::append_range(PreInits, OriginalInit); + + // List of OMPCapturedExprDecl, for __begin, __end, and NumIterations + if (auto *PI = cast_or_null(LoopHelper.PreInits)) { + PreInits.push_back(new (Context) DeclStmt( + PI->getDeclGroup(), PI->getBeginLoc(), PI->getEndLoc())); + } + + // Gather declarations for the data members used as counters. + for (Expr *CounterRef : LoopHelper.Counters) { + auto *CounterDecl = cast(CounterRef)->getDecl(); + if (isa(CounterDecl)) + PreInits.push_back(new (Context) DeclStmt( + DeclGroupRef(CounterDecl), SourceLocation(), SourceLocation())); + } +} + +/// Collect the loop statements (ForStmt or CXXRangeForStmt) of the affected +/// loop of a construct. +static void collectLoopStmts(Stmt *AStmt, MutableArrayRef LoopStmts) { + size_t NumLoops = LoopStmts.size(); + OMPLoopBasedDirective::doForAllLoops( + AStmt, /*TryImperfectlyNestedLoops=*/false, NumLoops, + [LoopStmts](unsigned Cnt, Stmt *CurStmt) { + assert(!LoopStmts[Cnt] && "Loop statement must not yet be assigned"); + LoopStmts[Cnt] = CurStmt; + return false; + }); + assert(!is_contained(LoopStmts, nullptr) && + "Expecting a loop statement for each affected loop"); +} + StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, @@ -15126,8 +15218,7 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, // Verify and diagnose loop nest. SmallVector LoopHelpers(NumLoops); Stmt *Body = nullptr; - SmallVector, 0>, 4> - OriginalInits; + SmallVector, 4> OriginalInits; if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, OriginalInits)) return StmtError(); @@ -15144,7 +15235,11 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, "Expecting loop iteration space dimensionality to match number of " "affected loops"); - SmallVector PreInits; + // Collect all affected loop statements. + SmallVector LoopStmts(NumLoops, nullptr); + collectLoopStmts(AStmt, LoopStmts); + + SmallVector PreInits; CaptureVars CopyTransformer(SemaRef); // Create iteration variables for the generated loops. @@ -15184,20 +15279,9 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, &SemaRef.PP.getIdentifierTable().get(TileCntName)); TileIndVars[I] = TileCntDecl; } - for (auto &P : OriginalInits[I]) { - if (auto *D = P.dyn_cast()) - PreInits.push_back(D); - else if (auto *PI = dyn_cast_or_null(P.dyn_cast())) - PreInits.append(PI->decl_begin(), PI->decl_end()); - } - if (auto *PI = cast_or_null(LoopHelper.PreInits)) - PreInits.append(PI->decl_begin(), PI->decl_end()); - // Gather declarations for the data members used as counters. - for (Expr *CounterRef : LoopHelper.Counters) { - auto *CounterDecl = cast(CounterRef)->getDecl(); - if (isa(CounterDecl)) - PreInits.push_back(CounterDecl); - } + + addLoopPreInits(Context, LoopHelper, LoopStmts[I], OriginalInits[I], + PreInits); } // Once the original iteration values are set, append the innermost body. @@ -15246,19 +15330,20 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; Expr *NumIterations = LoopHelper.NumIterations; auto *OrigCntVar = cast(LoopHelper.Counters[0]); - QualType CntTy = OrigCntVar->getType(); + QualType IVTy = NumIterations->getType(); + Stmt *LoopStmt = LoopStmts[I]; // Commonly used variables. One of the constraints of an AST is that every // node object must appear at most once, hence we define lamdas that create // a new AST node at every use. - auto MakeTileIVRef = [&SemaRef = this->SemaRef, &TileIndVars, I, CntTy, + auto MakeTileIVRef = [&SemaRef = this->SemaRef, &TileIndVars, I, IVTy, OrigCntVar]() { - return buildDeclRefExpr(SemaRef, TileIndVars[I], CntTy, + return buildDeclRefExpr(SemaRef, TileIndVars[I], IVTy, OrigCntVar->getExprLoc()); }; - auto MakeFloorIVRef = [&SemaRef = this->SemaRef, &FloorIndVars, I, CntTy, + auto MakeFloorIVRef = [&SemaRef = this->SemaRef, &FloorIndVars, I, IVTy, OrigCntVar]() { - return buildDeclRefExpr(SemaRef, FloorIndVars[I], CntTy, + return buildDeclRefExpr(SemaRef, FloorIndVars[I], IVTy, OrigCntVar->getExprLoc()); }; @@ -15320,6 +15405,8 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, // further into the inner loop. SmallVector BodyParts; BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); + if (auto *SourceCXXFor = dyn_cast(LoopStmt)) + BodyParts.push_back(SourceCXXFor->getLoopVarStmt()); BodyParts.push_back(Inner); Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(), Inner->getBeginLoc(), Inner->getEndLoc()); @@ -15334,12 +15421,14 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef Clauses, auto &LoopHelper = LoopHelpers[I]; Expr *NumIterations = LoopHelper.NumIterations; DeclRefExpr *OrigCntVar = cast(LoopHelper.Counters[0]); - QualType CntTy = OrigCntVar->getType(); + QualType IVTy = NumIterations->getType(); - // Commonly used variables. - auto MakeFloorIVRef = [&SemaRef = this->SemaRef, &FloorIndVars, I, CntTy, + // Commonly used variables. One of the constraints of an AST is that every + // node object must appear at most once, hence we define lamdas that create + // a new AST node at every use. + auto MakeFloorIVRef = [&SemaRef = this->SemaRef, &FloorIndVars, I, IVTy, OrigCntVar]() { - return buildDeclRefExpr(SemaRef, FloorIndVars[I], CntTy, + return buildDeclRefExpr(SemaRef, FloorIndVars[I], IVTy, OrigCntVar->getExprLoc()); }; @@ -15405,8 +15494,7 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses, Stmt *Body = nullptr; SmallVector LoopHelpers( NumLoops); - SmallVector, 0>, NumLoops + 1> - OriginalInits; + SmallVector, NumLoops + 1> OriginalInits; if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, Body, OriginalInits)) return StmtError(); @@ -15418,6 +15506,10 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses, return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, NumGeneratedLoops, nullptr, nullptr); + assert(LoopHelpers.size() == NumLoops && + "Expecting a single-dimensional loop iteration space"); + assert(OriginalInits.size() == NumLoops && + "Expecting a single-dimensional loop iteration space"); OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); if (FullClause) { @@ -15481,24 +15573,13 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses, // of a canonical loop nest where these PreInits are emitted before the // outermost directive. + // Find the loop statement. + Stmt *LoopStmt = nullptr; + collectLoopStmts(AStmt, {LoopStmt}); + // Determine the PreInit declarations. - SmallVector PreInits; - assert(OriginalInits.size() == 1 && - "Expecting a single-dimensional loop iteration space"); - for (auto &P : OriginalInits[0]) { - if (auto *D = P.dyn_cast()) - PreInits.push_back(D); - else if (auto *PI = dyn_cast_or_null(P.dyn_cast())) - PreInits.append(PI->decl_begin(), PI->decl_end()); - } - if (auto *PI = cast_or_null(LoopHelper.PreInits)) - PreInits.append(PI->decl_begin(), PI->decl_end()); - // Gather declarations for the data members used as counters. - for (Expr *CounterRef : LoopHelper.Counters) { - auto *CounterDecl = cast(CounterRef)->getDecl(); - if (isa(CounterDecl)) - PreInits.push_back(CounterDecl); - } + SmallVector PreInits; + addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits); auto *IterationVarRef = cast(LoopHelper.IterationVarRef); QualType IVTy = IterationVarRef->getType(); @@ -15604,6 +15685,8 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef Clauses, // Inner For statement. SmallVector InnerBodyStmts; InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); + if (auto *CXXRangeFor = dyn_cast(LoopStmt)) + InnerBodyStmts.push_back(CXXRangeFor->getLoopVarStmt()); InnerBodyStmts.push_back(Body); CompoundStmt *InnerBody = CompoundStmt::Create(getASTContext(), InnerBodyStmts, FPOptionsOverride(), diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 2eb25237a0de6..6c5e8afbcfb6e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -13,6 +13,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" +#include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DependenceFlags.h" @@ -1481,7 +1482,7 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, } if (OldMethod && NewMethod && !OldMethod->isStatic() && - !OldMethod->isStatic()) { + !NewMethod->isStatic()) { bool HaveCorrespondingObjectParameters = [&](const CXXMethodDecl *Old, const CXXMethodDecl *New) { auto NewObjectType = New->getFunctionObjectParameterReferenceType(); @@ -6472,17 +6473,20 @@ ExprResult Sema::InitializeExplicitObjectArgument(Sema &S, Expr *Obj, Obj->getExprLoc(), Obj); } -static void PrepareExplicitObjectArgument(Sema &S, CXXMethodDecl *Method, +static bool PrepareExplicitObjectArgument(Sema &S, CXXMethodDecl *Method, Expr *Object, MultiExprArg &Args, SmallVectorImpl &NewArgs) { assert(Method->isExplicitObjectMemberFunction() && "Method is not an explicit member function"); assert(NewArgs.empty() && "NewArgs should be empty"); + NewArgs.reserve(Args.size() + 1); Expr *This = GetExplicitObjectExpr(S, Object, Method); NewArgs.push_back(This); NewArgs.append(Args.begin(), Args.end()); Args = NewArgs; + return S.DiagnoseInvalidExplicitObjectParameterInLambda( + Method, Object->getBeginLoc()); } /// Determine whether the provided type is an integral type, or an enumeration @@ -11298,8 +11302,16 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, Expr *FromExpr = Conv.Bad.FromExpr; QualType FromTy = Conv.Bad.getFromType(); QualType ToTy = Conv.Bad.getToType(); - SourceRange ToParamRange = - !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : SourceRange(); + SourceRange ToParamRange; + + // FIXME: In presence of parameter packs we can't determine parameter range + // reliably, as we don't have access to instantiation. + bool HasParamPack = + llvm::any_of(Fn->parameters().take_front(I), [](const ParmVarDecl *Parm) { + return Parm->isParameterPack(); + }); + if (!isObjectArgument && !HasParamPack) + ToParamRange = Fn->getParamDecl(I)->getSourceRange(); if (FromTy == S.Context.OverloadTy) { assert(FromExpr && "overload set argument came from implicit argument?"); @@ -14351,7 +14363,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, if (Fn.isInvalid()) return ExprError(); return CXXOperatorCallExpr::Create(Context, Op, Fn.get(), ArgsArray, - Context.DependentTy, VK, OpLoc, + Context.DependentTy, VK_PRValue, OpLoc, CurFPFeatureOverrides()); } @@ -15612,8 +15624,10 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, CallExpr *TheCall = nullptr; llvm::SmallVector NewArgs; if (Method->isExplicitObjectMemberFunction()) { - PrepareExplicitObjectArgument(*this, Method, MemExpr->getBase(), Args, - NewArgs); + if (PrepareExplicitObjectArgument(*this, Method, MemExpr->getBase(), Args, + NewArgs)) + return ExprError(); + // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, FoundDecl, MemExpr, @@ -15927,9 +15941,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, // Initialize the object parameter. llvm::SmallVector NewArgs; if (Method->isExplicitObjectMemberFunction()) { - // FIXME: we should do that during the definition of the lambda when we can. - DiagnoseInvalidExplicitObjectParameterInLambda(Method); - PrepareExplicitObjectArgument(*this, Method, Obj, Args, NewArgs); + IsError |= PrepareExplicitObjectArgument(*this, Method, Obj, Args, NewArgs); } else { ExprResult ObjRes = PerformImplicitObjectArgumentInitialization( Object.get(), /*Qualifier=*/nullptr, Best->FoundDecl, Method); diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index 14ed9590afc6c..fdb584ceb8105 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -29,6 +29,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Sema/SemaPseudoObject.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/Basic/CharInfo.h" @@ -1446,24 +1447,24 @@ ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl, // General Sema routines. //===----------------------------------------------------------------------===// -ExprResult Sema::checkPseudoObjectRValue(Expr *E) { +ExprResult SemaPseudoObject::checkRValue(Expr *E) { Expr *opaqueRef = E->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast(opaqueRef)) { - ObjCPropertyOpBuilder builder(*this, refExpr, true); + ObjCPropertyOpBuilder builder(SemaRef, refExpr, true); return builder.buildRValueOperation(E); } else if (ObjCSubscriptRefExpr *refExpr = dyn_cast(opaqueRef)) { - ObjCSubscriptOpBuilder builder(*this, refExpr, true); + ObjCSubscriptOpBuilder builder(SemaRef, refExpr, true); return builder.buildRValueOperation(E); } else if (MSPropertyRefExpr *refExpr = dyn_cast(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr, true); + MSPropertyOpBuilder builder(SemaRef, refExpr, true); return builder.buildRValueOperation(E); } else if (MSPropertySubscriptExpr *RefExpr = dyn_cast(opaqueRef)) { - MSPropertyOpBuilder Builder(*this, RefExpr, true); + MSPropertyOpBuilder Builder(SemaRef, RefExpr, true); return Builder.buildRValueOperation(E); } else { llvm_unreachable("unknown pseudo-object kind!"); @@ -1471,48 +1472,48 @@ ExprResult Sema::checkPseudoObjectRValue(Expr *E) { } /// Check an increment or decrement of a pseudo-object expression. -ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, +ExprResult SemaPseudoObject::checkIncDec(Scope *Sc, SourceLocation opcLoc, UnaryOperatorKind opcode, Expr *op) { // Do nothing if the operand is dependent. if (op->isTypeDependent()) - return UnaryOperator::Create(Context, op, opcode, Context.DependentTy, - VK_PRValue, OK_Ordinary, opcLoc, false, - CurFPFeatureOverrides()); + return UnaryOperator::Create( + SemaRef.Context, op, opcode, SemaRef.Context.DependentTy, VK_PRValue, + OK_Ordinary, opcLoc, false, SemaRef.CurFPFeatureOverrides()); assert(UnaryOperator::isIncrementDecrementOp(opcode)); Expr *opaqueRef = op->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast(opaqueRef)) { - ObjCPropertyOpBuilder builder(*this, refExpr, false); + ObjCPropertyOpBuilder builder(SemaRef, refExpr, false); return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else if (isa(opaqueRef)) { Diag(opcLoc, diag::err_illegal_container_subscripting_op); return ExprError(); } else if (MSPropertyRefExpr *refExpr = dyn_cast(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr, false); + MSPropertyOpBuilder builder(SemaRef, refExpr, false); return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else if (MSPropertySubscriptExpr *RefExpr = dyn_cast(opaqueRef)) { - MSPropertyOpBuilder Builder(*this, RefExpr, false); + MSPropertyOpBuilder Builder(SemaRef, RefExpr, false); return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op); } else { llvm_unreachable("unknown pseudo-object kind!"); } } -ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, +ExprResult SemaPseudoObject::checkAssignment(Scope *S, SourceLocation opcLoc, BinaryOperatorKind opcode, Expr *LHS, Expr *RHS) { // Do nothing if either argument is dependent. if (LHS->isTypeDependent() || RHS->isTypeDependent()) - return BinaryOperator::Create(Context, LHS, RHS, opcode, - Context.DependentTy, VK_PRValue, OK_Ordinary, - opcLoc, CurFPFeatureOverrides()); + return BinaryOperator::Create( + SemaRef.Context, LHS, RHS, opcode, SemaRef.Context.DependentTy, + VK_PRValue, OK_Ordinary, opcLoc, SemaRef.CurFPFeatureOverrides()); // Filter out non-overload placeholder types in the RHS. if (RHS->getType()->isNonOverloadPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(RHS); + ExprResult result = SemaRef.CheckPlaceholderExpr(RHS); if (result.isInvalid()) return ExprError(); RHS = result.get(); } @@ -1521,20 +1522,20 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, Expr *opaqueRef = LHS->IgnoreParens(); if (ObjCPropertyRefExpr *refExpr = dyn_cast(opaqueRef)) { - ObjCPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign); + ObjCPropertyOpBuilder builder(SemaRef, refExpr, IsSimpleAssign); return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (ObjCSubscriptRefExpr *refExpr = dyn_cast(opaqueRef)) { - ObjCSubscriptOpBuilder builder(*this, refExpr, IsSimpleAssign); + ObjCSubscriptOpBuilder builder(SemaRef, refExpr, IsSimpleAssign); return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (MSPropertyRefExpr *refExpr = dyn_cast(opaqueRef)) { - MSPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign); - return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); + MSPropertyOpBuilder builder(SemaRef, refExpr, IsSimpleAssign); + return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else if (MSPropertySubscriptExpr *RefExpr = dyn_cast(opaqueRef)) { - MSPropertyOpBuilder Builder(*this, RefExpr, IsSimpleAssign); - return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); + MSPropertyOpBuilder Builder(SemaRef, RefExpr, IsSimpleAssign); + return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); } else { llvm_unreachable("unknown pseudo-object kind!"); } @@ -1557,36 +1558,38 @@ static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) { /// This is a hack which should be removed when TreeTransform is /// capable of rebuilding a tree without stripping implicit /// operations. -Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { +Expr *SemaPseudoObject::recreateSyntacticForm(PseudoObjectExpr *E) { Expr *syntax = E->getSyntacticForm(); if (UnaryOperator *uop = dyn_cast(syntax)) { - Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); - return UnaryOperator::Create(Context, op, uop->getOpcode(), uop->getType(), - uop->getValueKind(), uop->getObjectKind(), - uop->getOperatorLoc(), uop->canOverflow(), - CurFPFeatureOverrides()); + Expr *op = stripOpaqueValuesFromPseudoObjectRef(SemaRef, uop->getSubExpr()); + return UnaryOperator::Create( + SemaRef.Context, op, uop->getOpcode(), uop->getType(), + uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(), + uop->canOverflow(), SemaRef.CurFPFeatureOverrides()); } else if (CompoundAssignOperator *cop = dyn_cast(syntax)) { - Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); + Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(SemaRef, cop->getLHS()); Expr *rhs = cast(cop->getRHS())->getSourceExpr(); return CompoundAssignOperator::Create( - Context, lhs, rhs, cop->getOpcode(), cop->getType(), + SemaRef.Context, lhs, rhs, cop->getOpcode(), cop->getType(), cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(), - CurFPFeatureOverrides(), cop->getComputationLHSType(), + SemaRef.CurFPFeatureOverrides(), cop->getComputationLHSType(), cop->getComputationResultType()); } else if (BinaryOperator *bop = dyn_cast(syntax)) { - Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS()); + Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(SemaRef, bop->getLHS()); Expr *rhs = cast(bop->getRHS())->getSourceExpr(); - return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(), + return BinaryOperator::Create(SemaRef.Context, lhs, rhs, bop->getOpcode(), bop->getType(), bop->getValueKind(), bop->getObjectKind(), bop->getOperatorLoc(), - CurFPFeatureOverrides()); + SemaRef.CurFPFeatureOverrides()); } else if (isa(syntax)) { return syntax; } else { assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject)); - return stripOpaqueValuesFromPseudoObjectRef(*this, syntax); + return stripOpaqueValuesFromPseudoObjectRef(SemaRef, syntax); } } + +SemaPseudoObject::SemaPseudoObject(Sema &S) : SemaBase(S) {} diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index 26e13e87b1d6b..ea6e3f75490bc 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -1,4 +1,4 @@ -//==- SemaRISCVVectorLookup.cpp - Name Lookup for RISC-V Vector Intrinsic -==// +//===------ SemaRISCV.cpp ------- RISC-V target-specific routines ---------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,20 +6,24 @@ // //===----------------------------------------------------------------------===// // -// This file implements name lookup for RISC-V vector intrinsic. +// This file implements semantic analysis functions specific to RISC-V. // //===----------------------------------------------------------------------===// +#include "clang/Sema/SemaRISCV.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/RISCVIntrinsicManager.h" #include "clang/Sema/Sema.h" #include "clang/Support/RISCVVIntrinsicUtils.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include #include #include @@ -166,7 +170,6 @@ class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager { // Mapping function name to RVVOverloadIntrinsicDef. StringMap OverloadIntrinsics; - // Create RVVIntrinsicDef. void InitRVVIntrinsic(const RVVIntrinsicRecord &Record, StringRef SuffixStr, StringRef OverloadedSuffixStr, bool IsMask, @@ -342,18 +345,17 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics( /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P); } } // End for different LMUL - } // End for different TypeRange + } // End for different TypeRange } } void RISCVIntrinsicManagerImpl::InitIntrinsicList() { - if (S.DeclareRISCVVBuiltins && !ConstructedRISCVVBuiltins) { + if (S.RISCV().DeclareRVVBuiltins && !ConstructedRISCVVBuiltins) { ConstructedRISCVVBuiltins = true; - ConstructRVVIntrinsics(RVVIntrinsicRecords, - IntrinsicKind::RVV); + ConstructRVVIntrinsics(RVVIntrinsicRecords, IntrinsicKind::RVV); } - if (S.DeclareRISCVSiFiveVectorBuiltins && + if (S.RISCV().DeclareSiFiveVectorBuiltins && !ConstructedRISCVSiFiveVectorBuiltins) { ConstructedRISCVSiFiveVectorBuiltins = true; ConstructRVVIntrinsics(RVSiFiveVectorIntrinsicRecords, @@ -501,4 +503,925 @@ std::unique_ptr CreateRISCVIntrinsicManager(Sema &S) { return std::make_unique(S); } + +bool SemaRISCV::CheckLMUL(CallExpr *TheCall, unsigned ArgNum) { + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + int64_t Val = Result.getSExtValue(); + if ((Val >= 0 && Val <= 3) || (Val >= 5 && Val <= 7)) + return false; + + return Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_invalid_lmul) + << Arg->getSourceRange(); +} + +static bool CheckInvalidVLENandLMUL(const TargetInfo &TI, CallExpr *TheCall, + Sema &S, QualType Type, int EGW) { + assert((EGW == 128 || EGW == 256) && "EGW can only be 128 or 256 bits"); + + // LMUL * VLEN >= EGW + ASTContext::BuiltinVectorTypeInfo Info = + S.Context.getBuiltinVectorTypeInfo(Type->castAs()); + unsigned ElemSize = S.Context.getTypeSize(Info.ElementType); + unsigned MinElemCount = Info.EC.getKnownMinValue(); + + unsigned EGS = EGW / ElemSize; + // If EGS is less than or equal to the minimum number of elements, then the + // type is valid. + if (EGS <= MinElemCount) + return false; + + // Otherwise, we need vscale to be at least EGS / MinElemCont. + assert(EGS % MinElemCount == 0); + unsigned VScaleFactor = EGS / MinElemCount; + // Vscale is VLEN/RVVBitsPerBlock. + unsigned MinRequiredVLEN = VScaleFactor * llvm::RISCV::RVVBitsPerBlock; + std::string RequiredExt = "zvl" + std::to_string(MinRequiredVLEN) + "b"; + if (!TI.hasFeature(RequiredExt)) + return S.Diag(TheCall->getBeginLoc(), + diag::err_riscv_type_requires_extension) + << Type << RequiredExt; + + return false; +} + +bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI, + unsigned BuiltinID, + CallExpr *TheCall) { + ASTContext &Context = getASTContext(); + // vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx, + // vsmul.vv, vsmul.vx are not included for EEW=64 in Zve64*. + switch (BuiltinID) { + default: + break; + case RISCVVector::BI__builtin_rvv_vmulhsu_vv: + case RISCVVector::BI__builtin_rvv_vmulhsu_vx: + case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tu: + case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tu: + case RISCVVector::BI__builtin_rvv_vmulhsu_vv_m: + case RISCVVector::BI__builtin_rvv_vmulhsu_vx_m: + case RISCVVector::BI__builtin_rvv_vmulhsu_vv_mu: + case RISCVVector::BI__builtin_rvv_vmulhsu_vx_mu: + case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tum: + case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tum: + case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tumu: + case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tumu: + case RISCVVector::BI__builtin_rvv_vmulhu_vv: + case RISCVVector::BI__builtin_rvv_vmulhu_vx: + case RISCVVector::BI__builtin_rvv_vmulhu_vv_tu: + case RISCVVector::BI__builtin_rvv_vmulhu_vx_tu: + case RISCVVector::BI__builtin_rvv_vmulhu_vv_m: + case RISCVVector::BI__builtin_rvv_vmulhu_vx_m: + case RISCVVector::BI__builtin_rvv_vmulhu_vv_mu: + case RISCVVector::BI__builtin_rvv_vmulhu_vx_mu: + case RISCVVector::BI__builtin_rvv_vmulhu_vv_tum: + case RISCVVector::BI__builtin_rvv_vmulhu_vx_tum: + case RISCVVector::BI__builtin_rvv_vmulhu_vv_tumu: + case RISCVVector::BI__builtin_rvv_vmulhu_vx_tumu: + case RISCVVector::BI__builtin_rvv_vmulh_vv: + case RISCVVector::BI__builtin_rvv_vmulh_vx: + case RISCVVector::BI__builtin_rvv_vmulh_vv_tu: + case RISCVVector::BI__builtin_rvv_vmulh_vx_tu: + case RISCVVector::BI__builtin_rvv_vmulh_vv_m: + case RISCVVector::BI__builtin_rvv_vmulh_vx_m: + case RISCVVector::BI__builtin_rvv_vmulh_vv_mu: + case RISCVVector::BI__builtin_rvv_vmulh_vx_mu: + case RISCVVector::BI__builtin_rvv_vmulh_vv_tum: + case RISCVVector::BI__builtin_rvv_vmulh_vx_tum: + case RISCVVector::BI__builtin_rvv_vmulh_vv_tumu: + case RISCVVector::BI__builtin_rvv_vmulh_vx_tumu: + case RISCVVector::BI__builtin_rvv_vsmul_vv: + case RISCVVector::BI__builtin_rvv_vsmul_vx: + case RISCVVector::BI__builtin_rvv_vsmul_vv_tu: + case RISCVVector::BI__builtin_rvv_vsmul_vx_tu: + case RISCVVector::BI__builtin_rvv_vsmul_vv_m: + case RISCVVector::BI__builtin_rvv_vsmul_vx_m: + case RISCVVector::BI__builtin_rvv_vsmul_vv_mu: + case RISCVVector::BI__builtin_rvv_vsmul_vx_mu: + case RISCVVector::BI__builtin_rvv_vsmul_vv_tum: + case RISCVVector::BI__builtin_rvv_vsmul_vx_tum: + case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu: + case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu: { + ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo( + TheCall->getType()->castAs()); + + if (Context.getTypeSize(Info.ElementType) == 64 && !TI.hasFeature("v")) + return Diag(TheCall->getBeginLoc(), + diag::err_riscv_builtin_requires_extension) + << /* IsExtension */ true << TheCall->getSourceRange() << "v"; + + break; + } + } + + switch (BuiltinID) { + case RISCVVector::BI__builtin_rvv_vsetvli: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3) || + CheckLMUL(TheCall, 2); + case RISCVVector::BI__builtin_rvv_vsetvlimax: + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + CheckLMUL(TheCall, 1); + case RISCVVector::BI__builtin_rvv_vget_v: { + ASTContext::BuiltinVectorTypeInfo ResVecInfo = + Context.getBuiltinVectorTypeInfo(cast( + TheCall->getType().getCanonicalType().getTypePtr())); + ASTContext::BuiltinVectorTypeInfo VecInfo = + Context.getBuiltinVectorTypeInfo(cast( + TheCall->getArg(0)->getType().getCanonicalType().getTypePtr())); + unsigned MaxIndex; + if (VecInfo.NumVectors != 1) // vget for tuple type + MaxIndex = VecInfo.NumVectors; + else // vget for non-tuple type + MaxIndex = (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors) / + (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors); + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); + } + case RISCVVector::BI__builtin_rvv_vset_v: { + ASTContext::BuiltinVectorTypeInfo ResVecInfo = + Context.getBuiltinVectorTypeInfo(cast( + TheCall->getType().getCanonicalType().getTypePtr())); + ASTContext::BuiltinVectorTypeInfo VecInfo = + Context.getBuiltinVectorTypeInfo(cast( + TheCall->getArg(2)->getType().getCanonicalType().getTypePtr())); + unsigned MaxIndex; + if (ResVecInfo.NumVectors != 1) // vset for tuple type + MaxIndex = ResVecInfo.NumVectors; + else // vset fo non-tuple type + MaxIndex = (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors) / + (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors); + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); + } + // Vector Crypto + case RISCVVector::BI__builtin_rvv_vaeskf1_vi_tu: + case RISCVVector::BI__builtin_rvv_vaeskf2_vi_tu: + case RISCVVector::BI__builtin_rvv_vaeskf2_vi: + case RISCVVector::BI__builtin_rvv_vsm4k_vi_tu: { + QualType Op1Type = TheCall->getArg(0)->getType(); + QualType Op2Type = TheCall->getArg(1)->getType(); + return CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op1Type, 128) || + CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op2Type, 128) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31); + } + case RISCVVector::BI__builtin_rvv_vsm3c_vi_tu: + case RISCVVector::BI__builtin_rvv_vsm3c_vi: { + QualType Op1Type = TheCall->getArg(0)->getType(); + return CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op1Type, 256) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31); + } + case RISCVVector::BI__builtin_rvv_vaeskf1_vi: + case RISCVVector::BI__builtin_rvv_vsm4k_vi: { + QualType Op1Type = TheCall->getArg(0)->getType(); + return CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op1Type, 128) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + } + case RISCVVector::BI__builtin_rvv_vaesdf_vv: + case RISCVVector::BI__builtin_rvv_vaesdf_vs: + case RISCVVector::BI__builtin_rvv_vaesdm_vv: + case RISCVVector::BI__builtin_rvv_vaesdm_vs: + case RISCVVector::BI__builtin_rvv_vaesef_vv: + case RISCVVector::BI__builtin_rvv_vaesef_vs: + case RISCVVector::BI__builtin_rvv_vaesem_vv: + case RISCVVector::BI__builtin_rvv_vaesem_vs: + case RISCVVector::BI__builtin_rvv_vaesz_vs: + case RISCVVector::BI__builtin_rvv_vsm4r_vv: + case RISCVVector::BI__builtin_rvv_vsm4r_vs: + case RISCVVector::BI__builtin_rvv_vaesdf_vv_tu: + case RISCVVector::BI__builtin_rvv_vaesdf_vs_tu: + case RISCVVector::BI__builtin_rvv_vaesdm_vv_tu: + case RISCVVector::BI__builtin_rvv_vaesdm_vs_tu: + case RISCVVector::BI__builtin_rvv_vaesef_vv_tu: + case RISCVVector::BI__builtin_rvv_vaesef_vs_tu: + case RISCVVector::BI__builtin_rvv_vaesem_vv_tu: + case RISCVVector::BI__builtin_rvv_vaesem_vs_tu: + case RISCVVector::BI__builtin_rvv_vaesz_vs_tu: + case RISCVVector::BI__builtin_rvv_vsm4r_vv_tu: + case RISCVVector::BI__builtin_rvv_vsm4r_vs_tu: { + QualType Op1Type = TheCall->getArg(0)->getType(); + QualType Op2Type = TheCall->getArg(1)->getType(); + return CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op1Type, 128) || + CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op2Type, 128); + } + case RISCVVector::BI__builtin_rvv_vsha2ch_vv: + case RISCVVector::BI__builtin_rvv_vsha2cl_vv: + case RISCVVector::BI__builtin_rvv_vsha2ms_vv: + case RISCVVector::BI__builtin_rvv_vsha2ch_vv_tu: + case RISCVVector::BI__builtin_rvv_vsha2cl_vv_tu: + case RISCVVector::BI__builtin_rvv_vsha2ms_vv_tu: { + QualType Op1Type = TheCall->getArg(0)->getType(); + QualType Op2Type = TheCall->getArg(1)->getType(); + QualType Op3Type = TheCall->getArg(2)->getType(); + ASTContext::BuiltinVectorTypeInfo Info = + Context.getBuiltinVectorTypeInfo(Op1Type->castAs()); + uint64_t ElemSize = Context.getTypeSize(Info.ElementType); + if (ElemSize == 64 && !TI.hasFeature("zvknhb")) + return Diag(TheCall->getBeginLoc(), + diag::err_riscv_builtin_requires_extension) + << /* IsExtension */ true << TheCall->getSourceRange() << "zvknb"; + + return CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op1Type, + ElemSize * 4) || + CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op2Type, + ElemSize * 4) || + CheckInvalidVLENandLMUL(TI, TheCall, SemaRef, Op3Type, ElemSize * 4); + } + + case RISCVVector::BI__builtin_rvv_sf_vc_i_se: + // bit_27_26, bit_24_20, bit_11_7, simm5, sew, log2lmul + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, -16, 15) || + CheckLMUL(TheCall, 5); + case RISCVVector::BI__builtin_rvv_sf_vc_iv_se: + // bit_27_26, bit_11_7, vs2, simm5 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, -16, 15); + case RISCVVector::BI__builtin_rvv_sf_vc_v_i: + case RISCVVector::BI__builtin_rvv_sf_vc_v_i_se: + // bit_27_26, bit_24_20, simm5 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, -16, 15); + case RISCVVector::BI__builtin_rvv_sf_vc_v_iv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_iv_se: + // bit_27_26, vs2, simm5 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, -16, 15); + case RISCVVector::BI__builtin_rvv_sf_vc_ivv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_ivw_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_ivv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_ivw: + case RISCVVector::BI__builtin_rvv_sf_vc_v_ivv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_ivw_se: + // bit_27_26, vd, vs2, simm5 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 3, -16, 15); + case RISCVVector::BI__builtin_rvv_sf_vc_x_se: + // bit_27_26, bit_24_20, bit_11_7, xs1, sew, log2lmul + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) || + CheckLMUL(TheCall, 5); + case RISCVVector::BI__builtin_rvv_sf_vc_xv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_vv_se: + // bit_27_26, bit_11_7, vs2, xs1/vs1 + case RISCVVector::BI__builtin_rvv_sf_vc_v_x: + case RISCVVector::BI__builtin_rvv_sf_vc_v_x_se: + // bit_27_26, bit_24-20, xs1 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + case RISCVVector::BI__builtin_rvv_sf_vc_vvv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_xvv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_vvw_se: + case RISCVVector::BI__builtin_rvv_sf_vc_xvw_se: + // bit_27_26, vd, vs2, xs1 + case RISCVVector::BI__builtin_rvv_sf_vc_v_xv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_vv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_xv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_vv_se: + // bit_27_26, vs2, xs1/vs1 + case RISCVVector::BI__builtin_rvv_sf_vc_v_xvv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_vvv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_xvw: + case RISCVVector::BI__builtin_rvv_sf_vc_v_vvw: + case RISCVVector::BI__builtin_rvv_sf_vc_v_xvv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_vvv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_xvw_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_vvw_se: + // bit_27_26, vd, vs2, xs1/vs1 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3); + case RISCVVector::BI__builtin_rvv_sf_vc_fv_se: + // bit_26, bit_11_7, vs2, fs1 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1) || + SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31); + case RISCVVector::BI__builtin_rvv_sf_vc_fvv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_fvw_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_fvv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_fvw: + case RISCVVector::BI__builtin_rvv_sf_vc_v_fvv_se: + case RISCVVector::BI__builtin_rvv_sf_vc_v_fvw_se: + // bit_26, vd, vs2, fs1 + case RISCVVector::BI__builtin_rvv_sf_vc_v_fv: + case RISCVVector::BI__builtin_rvv_sf_vc_v_fv_se: + // bit_26, vs2, fs1 + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1); + // Check if byteselect is in [0, 3] + case RISCV::BI__builtin_riscv_aes32dsi: + case RISCV::BI__builtin_riscv_aes32dsmi: + case RISCV::BI__builtin_riscv_aes32esi: + case RISCV::BI__builtin_riscv_aes32esmi: + case RISCV::BI__builtin_riscv_sm4ks: + case RISCV::BI__builtin_riscv_sm4ed: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3); + // Check if rnum is in [0, 10] + case RISCV::BI__builtin_riscv_aes64ks1i: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 10); + // Check if value range for vxrm is in [0, 3] + case RISCVVector::BI__builtin_rvv_vaaddu_vv: + case RISCVVector::BI__builtin_rvv_vaaddu_vx: + case RISCVVector::BI__builtin_rvv_vaadd_vv: + case RISCVVector::BI__builtin_rvv_vaadd_vx: + case RISCVVector::BI__builtin_rvv_vasubu_vv: + case RISCVVector::BI__builtin_rvv_vasubu_vx: + case RISCVVector::BI__builtin_rvv_vasub_vv: + case RISCVVector::BI__builtin_rvv_vasub_vx: + case RISCVVector::BI__builtin_rvv_vsmul_vv: + case RISCVVector::BI__builtin_rvv_vsmul_vx: + case RISCVVector::BI__builtin_rvv_vssra_vv: + case RISCVVector::BI__builtin_rvv_vssra_vx: + case RISCVVector::BI__builtin_rvv_vssrl_vv: + case RISCVVector::BI__builtin_rvv_vssrl_vx: + case RISCVVector::BI__builtin_rvv_vnclip_wv: + case RISCVVector::BI__builtin_rvv_vnclip_wx: + case RISCVVector::BI__builtin_rvv_vnclipu_wv: + case RISCVVector::BI__builtin_rvv_vnclipu_wx: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3); + case RISCVVector::BI__builtin_rvv_vaaddu_vv_tu: + case RISCVVector::BI__builtin_rvv_vaaddu_vx_tu: + case RISCVVector::BI__builtin_rvv_vaadd_vv_tu: + case RISCVVector::BI__builtin_rvv_vaadd_vx_tu: + case RISCVVector::BI__builtin_rvv_vasubu_vv_tu: + case RISCVVector::BI__builtin_rvv_vasubu_vx_tu: + case RISCVVector::BI__builtin_rvv_vasub_vv_tu: + case RISCVVector::BI__builtin_rvv_vasub_vx_tu: + case RISCVVector::BI__builtin_rvv_vsmul_vv_tu: + case RISCVVector::BI__builtin_rvv_vsmul_vx_tu: + case RISCVVector::BI__builtin_rvv_vssra_vv_tu: + case RISCVVector::BI__builtin_rvv_vssra_vx_tu: + case RISCVVector::BI__builtin_rvv_vssrl_vv_tu: + case RISCVVector::BI__builtin_rvv_vssrl_vx_tu: + case RISCVVector::BI__builtin_rvv_vnclip_wv_tu: + case RISCVVector::BI__builtin_rvv_vnclip_wx_tu: + case RISCVVector::BI__builtin_rvv_vnclipu_wv_tu: + case RISCVVector::BI__builtin_rvv_vnclipu_wx_tu: + case RISCVVector::BI__builtin_rvv_vaaddu_vv_m: + case RISCVVector::BI__builtin_rvv_vaaddu_vx_m: + case RISCVVector::BI__builtin_rvv_vaadd_vv_m: + case RISCVVector::BI__builtin_rvv_vaadd_vx_m: + case RISCVVector::BI__builtin_rvv_vasubu_vv_m: + case RISCVVector::BI__builtin_rvv_vasubu_vx_m: + case RISCVVector::BI__builtin_rvv_vasub_vv_m: + case RISCVVector::BI__builtin_rvv_vasub_vx_m: + case RISCVVector::BI__builtin_rvv_vsmul_vv_m: + case RISCVVector::BI__builtin_rvv_vsmul_vx_m: + case RISCVVector::BI__builtin_rvv_vssra_vv_m: + case RISCVVector::BI__builtin_rvv_vssra_vx_m: + case RISCVVector::BI__builtin_rvv_vssrl_vv_m: + case RISCVVector::BI__builtin_rvv_vssrl_vx_m: + case RISCVVector::BI__builtin_rvv_vnclip_wv_m: + case RISCVVector::BI__builtin_rvv_vnclip_wx_m: + case RISCVVector::BI__builtin_rvv_vnclipu_wv_m: + case RISCVVector::BI__builtin_rvv_vnclipu_wx_m: + return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 3); + case RISCVVector::BI__builtin_rvv_vaaddu_vv_tum: + case RISCVVector::BI__builtin_rvv_vaaddu_vv_tumu: + case RISCVVector::BI__builtin_rvv_vaaddu_vv_mu: + case RISCVVector::BI__builtin_rvv_vaaddu_vx_tum: + case RISCVVector::BI__builtin_rvv_vaaddu_vx_tumu: + case RISCVVector::BI__builtin_rvv_vaaddu_vx_mu: + case RISCVVector::BI__builtin_rvv_vaadd_vv_tum: + case RISCVVector::BI__builtin_rvv_vaadd_vv_tumu: + case RISCVVector::BI__builtin_rvv_vaadd_vv_mu: + case RISCVVector::BI__builtin_rvv_vaadd_vx_tum: + case RISCVVector::BI__builtin_rvv_vaadd_vx_tumu: + case RISCVVector::BI__builtin_rvv_vaadd_vx_mu: + case RISCVVector::BI__builtin_rvv_vasubu_vv_tum: + case RISCVVector::BI__builtin_rvv_vasubu_vv_tumu: + case RISCVVector::BI__builtin_rvv_vasubu_vv_mu: + case RISCVVector::BI__builtin_rvv_vasubu_vx_tum: + case RISCVVector::BI__builtin_rvv_vasubu_vx_tumu: + case RISCVVector::BI__builtin_rvv_vasubu_vx_mu: + case RISCVVector::BI__builtin_rvv_vasub_vv_tum: + case RISCVVector::BI__builtin_rvv_vasub_vv_tumu: + case RISCVVector::BI__builtin_rvv_vasub_vv_mu: + case RISCVVector::BI__builtin_rvv_vasub_vx_tum: + case RISCVVector::BI__builtin_rvv_vasub_vx_tumu: + case RISCVVector::BI__builtin_rvv_vasub_vx_mu: + case RISCVVector::BI__builtin_rvv_vsmul_vv_mu: + case RISCVVector::BI__builtin_rvv_vsmul_vx_mu: + case RISCVVector::BI__builtin_rvv_vssra_vv_mu: + case RISCVVector::BI__builtin_rvv_vssra_vx_mu: + case RISCVVector::BI__builtin_rvv_vssrl_vv_mu: + case RISCVVector::BI__builtin_rvv_vssrl_vx_mu: + case RISCVVector::BI__builtin_rvv_vnclip_wv_mu: + case RISCVVector::BI__builtin_rvv_vnclip_wx_mu: + case RISCVVector::BI__builtin_rvv_vnclipu_wv_mu: + case RISCVVector::BI__builtin_rvv_vnclipu_wx_mu: + case RISCVVector::BI__builtin_rvv_vsmul_vv_tum: + case RISCVVector::BI__builtin_rvv_vsmul_vx_tum: + case RISCVVector::BI__builtin_rvv_vssra_vv_tum: + case RISCVVector::BI__builtin_rvv_vssra_vx_tum: + case RISCVVector::BI__builtin_rvv_vssrl_vv_tum: + case RISCVVector::BI__builtin_rvv_vssrl_vx_tum: + case RISCVVector::BI__builtin_rvv_vnclip_wv_tum: + case RISCVVector::BI__builtin_rvv_vnclip_wx_tum: + case RISCVVector::BI__builtin_rvv_vnclipu_wv_tum: + case RISCVVector::BI__builtin_rvv_vnclipu_wx_tum: + case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu: + case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu: + case RISCVVector::BI__builtin_rvv_vssra_vv_tumu: + case RISCVVector::BI__builtin_rvv_vssra_vx_tumu: + case RISCVVector::BI__builtin_rvv_vssrl_vv_tumu: + case RISCVVector::BI__builtin_rvv_vssrl_vx_tumu: + case RISCVVector::BI__builtin_rvv_vnclip_wv_tumu: + case RISCVVector::BI__builtin_rvv_vnclip_wx_tumu: + case RISCVVector::BI__builtin_rvv_vnclipu_wv_tumu: + case RISCVVector::BI__builtin_rvv_vnclipu_wx_tumu: + return SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 3); + case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm: + case RISCVVector::BI__builtin_rvv_vfrec7_v_rm: + case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm: + case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm: + case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm: + case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm: + case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm: + case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm: + case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm: + case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm: + case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm: + case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm: + case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 4); + case RISCVVector::BI__builtin_rvv_vfadd_vv_rm: + case RISCVVector::BI__builtin_rvv_vfadd_vf_rm: + case RISCVVector::BI__builtin_rvv_vfsub_vv_rm: + case RISCVVector::BI__builtin_rvv_vfsub_vf_rm: + case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm: + case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm: + case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm: + case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm: + case RISCVVector::BI__builtin_rvv_vfmul_vv_rm: + case RISCVVector::BI__builtin_rvv_vfmul_vf_rm: + case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm: + case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm: + case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm: + case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm: + case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm: + case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm: + case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm: + case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tu: + case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tu: + case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tu: + case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_m: + case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_m: + case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_m: + case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_m: + case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_m: + case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_m: + return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 4); + case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tu: + case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm: + case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm: + case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm: + case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm: + case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm: + case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm: + case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm: + case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm: + case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm: + case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm: + case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm: + case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm: + case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm: + case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm: + case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm: + case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm: + case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tu: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tu: + case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_m: + case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_m: + case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_m: + case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_m: + case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_m: + case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tum: + case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tum: + case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tum: + case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tum: + case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tum: + case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tum: + case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_mu: + case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_mu: + case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_mu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_mu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_mu: + case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_mu: + return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 4); + case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_m: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_m: + case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tum: + case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tum: + case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tum: + case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tum: + case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tumu: + case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_mu: + case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_mu: + return SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 4); + case RISCV::BI__builtin_riscv_ntl_load: + case RISCV::BI__builtin_riscv_ntl_store: + DeclRefExpr *DRE = + cast(TheCall->getCallee()->IgnoreParenCasts()); + assert((BuiltinID == RISCV::BI__builtin_riscv_ntl_store || + BuiltinID == RISCV::BI__builtin_riscv_ntl_load) && + "Unexpected RISC-V nontemporal load/store builtin!"); + bool IsStore = BuiltinID == RISCV::BI__builtin_riscv_ntl_store; + unsigned NumArgs = IsStore ? 3 : 2; + + if (SemaRef.checkArgCountAtLeast(TheCall, NumArgs - 1)) + return true; + + if (SemaRef.checkArgCountAtMost(TheCall, NumArgs)) + return true; + + // Domain value should be compile-time constant. + // 2 <= domain <= 5 + if (TheCall->getNumArgs() == NumArgs && + SemaRef.BuiltinConstantArgRange(TheCall, NumArgs - 1, 2, 5)) + return true; + + Expr *PointerArg = TheCall->getArg(0); + ExprResult PointerArgResult = + SemaRef.DefaultFunctionArrayLvalueConversion(PointerArg); + + if (PointerArgResult.isInvalid()) + return true; + PointerArg = PointerArgResult.get(); + + const PointerType *PtrType = PointerArg->getType()->getAs(); + if (!PtrType) { + Diag(DRE->getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer) + << PointerArg->getType() << PointerArg->getSourceRange(); + return true; + } + + QualType ValType = PtrType->getPointeeType(); + ValType = ValType.getUnqualifiedType(); + if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && + !ValType->isBlockPointerType() && !ValType->isFloatingType() && + !ValType->isVectorType() && !ValType->isRVVSizelessBuiltinType()) { + Diag(DRE->getBeginLoc(), + diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector) + << PointerArg->getType() << PointerArg->getSourceRange(); + return true; + } + + if (!IsStore) { + TheCall->setType(ValType); + return false; + } + + ExprResult ValArg = TheCall->getArg(1); + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Context, ValType, /*consume*/ false); + ValArg = + SemaRef.PerformCopyInitialization(Entity, SourceLocation(), ValArg); + if (ValArg.isInvalid()) + return true; + + TheCall->setArg(1, ValArg.get()); + TheCall->setType(Context.VoidTy); + return false; + } + + return false; +} + +void SemaRISCV::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D, + const llvm::StringMap &FeatureMap) { + ASTContext::BuiltinVectorTypeInfo Info = + SemaRef.Context.getBuiltinVectorTypeInfo(Ty->castAs()); + unsigned EltSize = SemaRef.Context.getTypeSize(Info.ElementType); + unsigned MinElts = Info.EC.getKnownMinValue(); + + if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Double) && + !FeatureMap.lookup("zve64d")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64d"; + // (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at + // least zve64x + else if (((EltSize == 64 && Info.ElementType->isIntegerType()) || + MinElts == 1) && + !FeatureMap.lookup("zve64x")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x"; + else if (Info.ElementType->isFloat16Type() && !FeatureMap.lookup("zvfh") && + !FeatureMap.lookup("zvfhmin")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) + << Ty << "zvfh or zvfhmin"; + else if (Info.ElementType->isBFloat16Type() && + !FeatureMap.lookup("experimental-zvfbfmin")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin"; + else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) && + !FeatureMap.lookup("zve32f")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f"; + // Given that caller already checked isRVVType() before calling this function, + // if we don't have at least zve32x supported, then we need to emit error. + else if (!FeatureMap.lookup("zve32x")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x"; +} + +/// Are the two types RVV-bitcast-compatible types? I.e. is bitcasting from the +/// first RVV type (e.g. an RVV scalable type) to the second type (e.g. an RVV +/// VLS type) allowed? +/// +/// This will also return false if the two given types do not make sense from +/// the perspective of RVV bitcasts. +bool SemaRISCV::isValidRVVBitcast(QualType srcTy, QualType destTy) { + assert(srcTy->isVectorType() || destTy->isVectorType()); + + auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) { + if (!FirstType->isRVVSizelessBuiltinType()) + return false; + + const auto *VecTy = SecondType->getAs(); + return VecTy && VecTy->getVectorKind() == VectorKind::RVVFixedLengthData; + }; + + return ValidScalableConversion(srcTy, destTy) || + ValidScalableConversion(destTy, srcTy); +} + +SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {} + } // namespace clang diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 36f8ecadcfab7..8735d96c84079 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -665,7 +665,8 @@ bool Sema::CheckRebuiltStmtAttributes(ArrayRef Attrs) { ExprResult Sema::ActOnCXXAssumeAttr(Stmt *St, const ParsedAttr &A, SourceRange Range) { if (A.getNumArgs() != 1 || !A.getArgAsExpr(0)) { - Diag(A.getLoc(), diag::err_assume_attr_args) << A.getAttrName() << Range; + Diag(A.getLoc(), diag::err_attribute_wrong_number_arguments) + << A.getAttrName() << 1 << Range; return ExprError(); } @@ -682,8 +683,11 @@ ExprResult Sema::ActOnCXXAssumeAttr(Stmt *St, const ParsedAttr &A, Assumption = Res.get(); } - if (!getLangOpts().CPlusPlus23) + if (!getLangOpts().CPlusPlus23 && + A.getSyntax() == AttributeCommonInfo::AS_CXX11) { + llvm::dbgs() << "Syntax: " << int(A.getSyntax()) << "\n"; Diag(A.getLoc(), diag::ext_cxx23_attr) << A << Range; + } return Assumption; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 02d9b64c2b14b..39e9dbed0c3e0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1071,7 +1071,8 @@ NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename, return Param; } - Param->setDefaultArgument(DefaultTInfo); + Param->setDefaultArgument( + Context, TemplateArgumentLoc(DefaultTInfo->getType(), DefaultTInfo)); } return Param; @@ -1598,7 +1599,9 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, if (DiagnoseUnexpandedParameterPack(Default, UPPC_DefaultArgument)) return Param; - Param->setDefaultArgument(Default); + Param->setDefaultArgument( + Context, getTrivialTemplateArgumentLoc(TemplateArgument(Default), + QualType(), SourceLocation())); } return Param; @@ -1839,7 +1842,8 @@ DeclResult Sema::CheckClassTemplate( TemplateParameterList **OuterTemplateParamLists, SkipBodyInfo *SkipBody) { assert(TemplateParams && TemplateParams->size() > 0 && "No template parameters"); - assert(TUK != TUK_Reference && "Can only declare or define class templates"); + assert(TUK != TagUseKind::Reference && + "Can only declare or define class templates"); bool Invalid = false; // Check that we can declare a template here. @@ -1861,8 +1865,9 @@ DeclResult Sema::CheckClassTemplate( // C++11 [basic.lookup.elab]p2). DeclContext *SemanticContext; LookupResult Previous(*this, Name, NameLoc, - (SS.isEmpty() && TUK == TUK_Friend) - ? LookupTagName : LookupOrdinaryName, + (SS.isEmpty() && TUK == TagUseKind::Friend) + ? LookupTagName + : LookupOrdinaryName, forRedeclarationInCurContext()); if (SS.isNotEmpty() && !SS.isInvalid()) { SemanticContext = computeDeclContext(SS, true); @@ -1870,11 +1875,11 @@ DeclResult Sema::CheckClassTemplate( // FIXME: Horrible, horrible hack! We can't currently represent this // in the AST, and historically we have just ignored such friend // class templates, so don't complain here. - Diag(NameLoc, TUK == TUK_Friend + Diag(NameLoc, TUK == TagUseKind::Friend ? diag::warn_template_qualified_friend_ignored : diag::err_template_qualified_declarator_no_match) << SS.getScopeRep() << SS.getRange(); - return TUK != TUK_Friend; + return TUK != TagUseKind::Friend; } if (RequireCompleteDeclContext(SS, SemanticContext)) @@ -1889,7 +1894,7 @@ DeclResult Sema::CheckClassTemplate( Invalid = true; } - if (TUK != TUK_Friend && TUK != TUK_Reference) + if (TUK != TagUseKind::Friend && TUK != TagUseKind::Reference) diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc, /*TemplateId-*/ nullptr, /*IsMemberSpecialization*/ false); @@ -1902,7 +1907,7 @@ DeclResult Sema::CheckClassTemplate( // If T is the name of a class, then each of the following shall have a // name different from T: // -- every member template of class T - if (TUK != TUK_Friend && + if (TUK != TagUseKind::Friend && DiagnoseClassNameShadow(SemanticContext, DeclarationNameInfo(Name, NameLoc))) return true; @@ -1944,7 +1949,7 @@ DeclResult Sema::CheckClassTemplate( } } - if (TUK == TUK_Friend) { + if (TUK == TagUseKind::Friend) { // C++ [namespace.memdef]p3: // [...] When looking for a prior declaration of a class or a function // declared as a friend, and when the name of the friend class or @@ -1981,9 +1986,8 @@ DeclResult Sema::CheckClassTemplate( PrevDecl = (*Previous.begin())->getUnderlyingDecl(); } } - } else if (PrevDecl && - !isDeclInScope(Previous.getRepresentativeDecl(), SemanticContext, - S, SS.isValid())) + } else if (PrevDecl && !isDeclInScope(Previous.getRepresentativeDecl(), + SemanticContext, S, SS.isValid())) PrevDecl = PrevClassTemplate = nullptr; if (auto *Shadow = dyn_cast_or_null( @@ -2005,7 +2009,7 @@ DeclResult Sema::CheckClassTemplate( // Ensure that the template parameter lists are compatible. Skip this check // for a friend in a dependent context: the template parameter list itself // could be dependent. - if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && + if (!(TUK == TagUseKind::Friend && CurContext->isDependentContext()) && !TemplateParameterListsAreEqual( TemplateCompareNewDeclInfo(SemanticContext ? SemanticContext : CurContext, @@ -2021,8 +2025,8 @@ DeclResult Sema::CheckClassTemplate( // the class-key shall agree in kind with the original class // template declaration (7.1.5.3). RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl(); - if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind, - TUK == TUK_Definition, KWLoc, Name)) { + if (!isAcceptableTagRedeclaration( + PrevRecordDecl, Kind, TUK == TagUseKind::Definition, KWLoc, Name)) { Diag(KWLoc, diag::err_use_with_wrong_tag) << Name << FixItHint::CreateReplacement(KWLoc, PrevRecordDecl->getKindName()); @@ -2031,7 +2035,7 @@ DeclResult Sema::CheckClassTemplate( } // Check for redefinition of this class template. - if (TUK == TUK_Definition) { + if (TUK == TagUseKind::Definition) { if (TagDecl *Def = PrevRecordDecl->getDefinition()) { // If we have a prior definition that is not visible, treat this as // simply making that previous definition visible. @@ -2068,7 +2072,7 @@ DeclResult Sema::CheckClassTemplate( // merging in the template parameter list from the previous class // template declaration. Skip this check for a friend in a dependent // context, because the template parameter list might be dependent. - if (!(TUK == TUK_Friend && CurContext->isDependentContext()) && + if (!(TUK == TagUseKind::Friend && CurContext->isDependentContext()) && CheckTemplateParameterList( TemplateParams, PrevClassTemplate ? GetTemplateParameterList(PrevClassTemplate) @@ -2076,8 +2080,8 @@ DeclResult Sema::CheckClassTemplate( (SS.isSet() && SemanticContext && SemanticContext->isRecord() && SemanticContext->isDependentContext()) ? TPC_ClassTemplateMember - : TUK == TUK_Friend ? TPC_FriendClassTemplate - : TPC_ClassTemplate, + : TUK == TagUseKind::Friend ? TPC_FriendClassTemplate + : TPC_ClassTemplate, SkipBody)) Invalid = true; @@ -2085,9 +2089,10 @@ DeclResult Sema::CheckClassTemplate( // If the name of the template was qualified, we must be defining the // template out-of-line. if (!SS.isInvalid() && !Invalid && !PrevClassTemplate) { - Diag(NameLoc, TUK == TUK_Friend ? diag::err_friend_decl_does_not_match - : diag::err_member_decl_does_not_match) - << Name << SemanticContext << /*IsDefinition*/true << SS.getRange(); + Diag(NameLoc, TUK == TagUseKind::Friend + ? diag::err_friend_decl_does_not_match + : diag::err_member_decl_does_not_match) + << Name << SemanticContext << /*IsDefinition*/ true << SS.getRange(); Invalid = true; } } @@ -2097,8 +2102,8 @@ DeclResult Sema::CheckClassTemplate( // recent declaration tricking the template instantiator to make substitutions // there. // FIXME: Figure out how to combine with shouldLinkDependentDeclWithPrevious - bool ShouldAddRedecl - = !(TUK == TUK_Friend && CurContext->isDependentContext()); + bool ShouldAddRedecl = + !(TUK == TagUseKind::Friend && CurContext->isDependentContext()); CXXRecordDecl *NewClass = CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name, @@ -2113,7 +2118,7 @@ DeclResult Sema::CheckClassTemplate( // Add alignment attributes if necessary; these attributes are checked when // the ASTContext lays out the structure. - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) { + if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip)) { AddAlignmentAttributesForRecord(NewClass); AddMsStructLayoutForRecord(NewClass); } @@ -2144,14 +2149,15 @@ DeclResult Sema::CheckClassTemplate( PrevClassTemplate->setMemberSpecialization(); // Set the access specifier. - if (!Invalid && TUK != TUK_Friend && NewTemplate->getDeclContext()->isRecord()) + if (!Invalid && TUK != TagUseKind::Friend && + NewTemplate->getDeclContext()->isRecord()) SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS); // Set the lexical context of these templates NewClass->setLexicalDeclContext(CurContext); NewTemplate->setLexicalDeclContext(CurContext); - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) + if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip)) NewClass->startDefinition(); ProcessDeclAttributeList(S, NewClass, Attr); @@ -2164,7 +2170,7 @@ DeclResult Sema::CheckClassTemplate( inferGslOwnerPointerAttribute(NewClass); inferNullableClassAttribute(NewClass); - if (TUK != TUK_Friend) { + if (TUK != TagUseKind::Friend) { // Per C++ [basic.scope.temp]p2, skip the template parameter scopes. Scope *Outer = S; while ((Outer->getFlags() & Scope::TemplateParamScope) != 0) @@ -2318,11 +2324,11 @@ transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC, SemaRef.SubstTypeConstraint(NewTTP, TC, Args, /*EvaluateConstraint=*/true); if (TTP->hasDefaultArgument()) { - TypeSourceInfo *InstantiatedDefaultArg = - SemaRef.SubstType(TTP->getDefaultArgumentInfo(), Args, - TTP->getDefaultArgumentLoc(), TTP->getDeclName()); - if (InstantiatedDefaultArg) - NewTTP->setDefaultArgument(InstantiatedDefaultArg); + TemplateArgumentLoc InstantiatedDefaultArg; + if (!SemaRef.SubstTemplateArgument( + TTP->getDefaultArgument(), Args, InstantiatedDefaultArg, + TTP->getDefaultArgumentLoc(), TTP->getDeclName())) + NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg); } SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP); return NewTTP; @@ -3575,10 +3581,9 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, = dyn_cast(*NewParam)) { // Check the presence of a default argument here. if (NewTypeParm->hasDefaultArgument() && - DiagnoseDefaultTemplateArgument(*this, TPC, - NewTypeParm->getLocation(), - NewTypeParm->getDefaultArgumentInfo()->getTypeLoc() - .getSourceRange())) + DiagnoseDefaultTemplateArgument( + *this, TPC, NewTypeParm->getLocation(), + NewTypeParm->getDefaultArgument().getSourceRange())) NewTypeParm->removeDefaultArgument(); // Merge default arguments for template type parameters. @@ -3627,9 +3632,9 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, // Check the presence of a default argument here. if (NewNonTypeParm->hasDefaultArgument() && - DiagnoseDefaultTemplateArgument(*this, TPC, - NewNonTypeParm->getLocation(), - NewNonTypeParm->getDefaultArgument()->getSourceRange())) { + DiagnoseDefaultTemplateArgument( + *this, TPC, NewNonTypeParm->getLocation(), + NewNonTypeParm->getDefaultArgument().getSourceRange())) { NewNonTypeParm->removeDefaultArgument(); } @@ -5015,7 +5020,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, IdentifierInfo *Id = D->getIdentifier(); assert(Id && "templated class must have an identifier"); - if (!isAcceptableTagRedeclaration(D, TagKind, TUK == TUK_Definition, + if (!isAcceptableTagRedeclaration(D, TagKind, TUK == TagUseKind::Definition, TagLoc, Id)) { Diag(TagLoc, diag::err_use_with_wrong_tag) << Result @@ -6040,22 +6045,26 @@ bool Sema::CheckTemplateTypeArgument( /// /// \param Converted the list of template arguments provided for template /// parameters that precede \p Param in the template parameter list. -/// \returns the substituted template argument, or NULL if an error occurred. -static TypeSourceInfo *SubstDefaultTemplateArgument( +/// +/// \param Output the resulting substituted template argument. +/// +/// \returns true if an error occurred. +static bool SubstDefaultTemplateArgument( Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, TemplateTypeParmDecl *Param, ArrayRef SugaredConverted, - ArrayRef CanonicalConverted) { - TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo(); + ArrayRef CanonicalConverted, + TemplateArgumentLoc &Output) { + Output = Param->getDefaultArgument(); // If the argument type is dependent, instantiate it now based // on the previously-computed template arguments. - if (ArgType->getType()->isInstantiationDependentType()) { + if (Output.getArgument().isInstantiationDependent()) { Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template, SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) - return nullptr; + return true; // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted, @@ -6068,12 +6077,14 @@ static TypeSourceInfo *SubstDefaultTemplateArgument( ForLambdaCallOperator = Rec->isLambda(); Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext(), !ForLambdaCallOperator); - ArgType = - SemaRef.SubstType(ArgType, TemplateArgLists, - Param->getDefaultArgumentLoc(), Param->getDeclName()); + + if (SemaRef.SubstTemplateArgument(Output, TemplateArgLists, Output, + Param->getDefaultArgumentLoc(), + Param->getDeclName())) + return true; } - return ArgType; + return false; } /// Substitute template arguments into the default template argument for @@ -6098,16 +6109,17 @@ static TypeSourceInfo *SubstDefaultTemplateArgument( /// parameters that precede \p Param in the template parameter list. /// /// \returns the substituted template argument, or NULL if an error occurred. -static ExprResult SubstDefaultTemplateArgument( +static bool SubstDefaultTemplateArgument( Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, NonTypeTemplateParmDecl *Param, ArrayRef SugaredConverted, - ArrayRef CanonicalConverted) { + ArrayRef CanonicalConverted, + TemplateArgumentLoc &Output) { Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template, SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) - return ExprError(); + return true; // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted, @@ -6118,7 +6130,8 @@ static ExprResult SubstDefaultTemplateArgument( Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext()); EnterExpressionEvaluationContext ConstantEvaluated( SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - return SemaRef.SubstExpr(Param->getDefaultArgument(), TemplateArgLists); + return SemaRef.SubstTemplateArgument(Param->getDefaultArgument(), + TemplateArgLists, Output); } /// Substitute template arguments into the default template argument for @@ -6196,13 +6209,12 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable( return TemplateArgumentLoc(); HasDefaultArg = true; - TypeSourceInfo *DI = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, TypeParm, SugaredConverted, - CanonicalConverted); - if (DI) - return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); - - return TemplateArgumentLoc(); + TemplateArgumentLoc Output; + if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, + TypeParm, SugaredConverted, + CanonicalConverted, Output)) + return TemplateArgumentLoc(); + return Output; } if (NonTypeTemplateParmDecl *NonTypeParm @@ -6211,14 +6223,12 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable( return TemplateArgumentLoc(); HasDefaultArg = true; - ExprResult Arg = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, NonTypeParm, SugaredConverted, - CanonicalConverted); - if (Arg.isInvalid()) + TemplateArgumentLoc Output; + if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, + NonTypeParm, SugaredConverted, + CanonicalConverted, Output)) return TemplateArgumentLoc(); - - Expr *ArgE = Arg.getAs(); - return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE); + return Output; } TemplateTemplateParmDecl *TempTempParm @@ -6785,28 +6795,20 @@ bool Sema::CheckTemplateArgumentList( return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP, NewArgs); - TypeSourceInfo *ArgType = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, TTP, SugaredConverted, - CanonicalConverted); - if (!ArgType) + if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, + TTP, SugaredConverted, + CanonicalConverted, Arg)) return true; - - Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()), - ArgType); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*Param)) { if (!hasReachableDefaultArgument(NTTP)) return diagnoseMissingArgument(*this, TemplateLoc, Template, NTTP, NewArgs); - ExprResult E = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, NTTP, SugaredConverted, - CanonicalConverted); - if (E.isInvalid()) + if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, + NTTP, SugaredConverted, + CanonicalConverted, Arg)) return true; - - Expr *Ex = E.getAs(); - Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex); } else { TemplateTemplateParmDecl *TempParm = cast(*Param); @@ -9451,7 +9453,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr, MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody) { - assert(TUK != TUK_Reference && "References are not specializations"); + assert(TUK != TagUseKind::Reference && "References are not specializations"); SourceLocation TemplateNameLoc = TemplateId.TemplateNameLoc; SourceLocation LAngleLoc = TemplateId.LAngleLoc; @@ -9473,7 +9475,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( bool isPartialSpecialization = false; if (SS.isSet()) { - if (TUK != TUK_Reference && TUK != TUK_Friend && + if (TUK != TagUseKind::Reference && TUK != TagUseKind::Friend && diagnoseQualifiedDeclaration(SS, ClassTemplate->getDeclContext(), ClassTemplate->getDeclName(), TemplateNameLoc, &TemplateId, @@ -9488,9 +9490,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization( bool Invalid = false; TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - KWLoc, TemplateNameLoc, SS, &TemplateId, - TemplateParameterLists, TUK == TUK_Friend, isMemberSpecialization, - Invalid); + KWLoc, TemplateNameLoc, SS, &TemplateId, TemplateParameterLists, + TUK == TagUseKind::Friend, isMemberSpecialization, Invalid); if (Invalid) return true; @@ -9501,7 +9502,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( if (TemplateParams && TemplateParams->size() > 0) { isPartialSpecialization = true; - if (TUK == TUK_Friend) { + if (TUK == TagUseKind::Friend) { Diag(KWLoc, diag::err_partial_specialization_friend) << SourceRange(LAngleLoc, RAngleLoc); return true; @@ -9520,10 +9521,10 @@ DeclResult Sema::ActOnClassTemplateSpecialization( } } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(Param)) { - if (Expr *DefArg = NTTP->getDefaultArgument()) { + if (NTTP->hasDefaultArgument()) { Diag(NTTP->getDefaultArgumentLoc(), diag::err_default_arg_in_partial_spec) - << DefArg->getSourceRange(); + << NTTP->getDefaultArgument().getSourceRange(); NTTP->removeDefaultArgument(); } } else { @@ -9537,14 +9538,15 @@ DeclResult Sema::ActOnClassTemplateSpecialization( } } } else if (TemplateParams) { - if (TUK == TUK_Friend) + if (TUK == TagUseKind::Friend) Diag(KWLoc, diag::err_template_spec_friend) << FixItHint::CreateRemoval( SourceRange(TemplateParams->getTemplateLoc(), TemplateParams->getRAngleLoc())) << SourceRange(LAngleLoc, RAngleLoc); } else { - assert(TUK == TUK_Friend && "should have a 'template<>' for this decl"); + assert(TUK == TagUseKind::Friend && + "should have a 'template<>' for this decl"); } // Check that the specialization uses the same tag kind as the @@ -9552,8 +9554,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization( TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); assert(Kind != TagTypeKind::Enum && "Invalid enum tag in class template spec!"); - if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), - Kind, TUK == TUK_Definition, KWLoc, + if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), Kind, + TUK == TagUseKind::Definition, KWLoc, ClassTemplate->getIdentifier())) { Diag(KWLoc, diag::err_use_with_wrong_tag) << ClassTemplate @@ -9617,7 +9619,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( // Check whether we can declare a class template specialization in // the current scope. - if (TUK != TUK_Friend && + if (TUK != TagUseKind::Friend && CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl, TemplateNameLoc, isPartialSpecialization)) @@ -9644,8 +9646,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization( // This rule has since been removed, because it's redundant given DR1495, // but we keep it because it produces better diagnostics and recovery. Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template) - << /*class template*/0 << (TUK == TUK_Definition) - << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc)); + << /*class template*/ 0 << (TUK == TagUseKind::Definition) + << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc)); return CheckClassTemplate(S, TagSpec, TUK, KWLoc, SS, ClassTemplate->getIdentifier(), TemplateNameLoc, @@ -9737,11 +9739,11 @@ DeclResult Sema::ActOnClassTemplateSpecialization( } // If this is not a friend, note that this is an explicit specialization. - if (TUK != TUK_Friend) + if (TUK != TagUseKind::Friend) Specialization->setSpecializationKind(TSK_ExplicitSpecialization); // Check that this isn't a redefinition of this specialization. - if (TUK == TUK_Definition) { + if (TUK == TagUseKind::Definition) { RecordDecl *Def = Specialization->getDefinition(); NamedDecl *Hidden = nullptr; if (Def && SkipBody && !hasVisibleDefinition(Def, &Hidden)) { @@ -9762,7 +9764,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( // Add alignment attributes if necessary; these attributes are checked when // the ASTContext lays out the structure. - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) { + if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip)) { AddAlignmentAttributesForRecord(Specialization); AddMsStructLayoutForRecord(Specialization); } @@ -9783,10 +9785,10 @@ DeclResult Sema::ActOnClassTemplateSpecialization( Specialization->setLexicalDeclContext(CurContext); // We may be starting the definition of this specialization. - if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) + if (TUK == TagUseKind::Definition && (!SkipBody || !SkipBody->ShouldSkip)) Specialization->startDefinition(); - if (TUK == TUK_Friend) { + if (TUK == TagUseKind::Friend) { // Build the fully-sugared type for this class template // specialization as the user wrote in the specialization // itself. This means that we'll pretty-print the type retrieved @@ -11160,11 +11162,13 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, bool Owned = false; bool IsDependent = false; - Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, - NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(), + Decl *TagD = + ActOnTag(S, TagSpec, TagUseKind::Reference, KWLoc, SS, Name, NameLoc, + Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, IsDependent, SourceLocation(), false, TypeResult(), /*IsTypeSpecifier*/ false, - /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside).get(); + /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside) + .get(); assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); if (!TagD) @@ -11695,9 +11699,9 @@ TypeResult Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); - if (TUK == TUK_Declaration || TUK == TUK_Definition) { + if (TUK == TagUseKind::Declaration || TUK == TagUseKind::Definition) { Diag(NameLoc, diag::err_dependent_tag_decl) - << (TUK == TUK_Definition) << llvm::to_underlying(Kind) + << (TUK == TagUseKind::Definition) << llvm::to_underlying(Kind) << SS.getRange(); return true; } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 41fd210f29d09..f9ec34163e656 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -519,18 +519,14 @@ static NamedDecl *getTemplateParameterWithDefault(Sema &S, NamedDecl *A, switch (A->getKind()) { case Decl::TemplateTypeParm: { auto *T = cast(A); - // FIXME: A TemplateTypeParmDecl's DefaultArgument can't hold a full - // TemplateArgument, so there is currently no way to specify a pack as a - // default argument for these. - if (T->isParameterPack()) - return A; auto *R = TemplateTypeParmDecl::Create( S.Context, A->getDeclContext(), SourceLocation(), SourceLocation(), T->getDepth(), T->getIndex(), T->getIdentifier(), - T->wasDeclaredWithTypename(), /*ParameterPack=*/false, + T->wasDeclaredWithTypename(), T->isParameterPack(), T->hasTypeConstraint()); R->setDefaultArgument( - S.Context.getTrivialTypeSourceInfo(Default.getAsType())); + S.Context, + S.getTrivialTemplateArgumentLoc(Default, QualType(), SourceLocation())); if (R->hasTypeConstraint()) { auto *C = R->getTypeConstraint(); R->setTypeConstraint(C->getConceptReference(), @@ -540,14 +536,14 @@ static NamedDecl *getTemplateParameterWithDefault(Sema &S, NamedDecl *A, } case Decl::NonTypeTemplateParm: { auto *T = cast(A); - // FIXME: Ditto, as above for TemplateTypeParm case. - if (T->isParameterPack()) - return A; auto *R = NonTypeTemplateParmDecl::Create( S.Context, A->getDeclContext(), SourceLocation(), SourceLocation(), T->getDepth(), T->getIndex(), T->getIdentifier(), T->getType(), - /*ParameterPack=*/false, T->getTypeSourceInfo()); - R->setDefaultArgument(Default.getAsExpr()); + T->isParameterPack(), T->getTypeSourceInfo()); + R->setDefaultArgument(S.Context, + S.getTrivialTemplateArgumentLoc( + Default, Default.getNonTypeTemplateArgumentType(), + SourceLocation())); if (auto *PTC = T->getPlaceholderTypeConstraint()) R->setPlaceholderTypeConstraint(PTC); return R; @@ -4776,8 +4772,13 @@ TemplateDeductionResult Sema::DeduceTemplateArguments( DeduceReturnType(Specialization, Info.getLocation(), false)) return TemplateDeductionResult::MiscellaneousDeductionFailure; + // [C++26][expr.const]/p17 + // An expression or conversion is immediate-escalating if it is not initially + // in an immediate function context and it is [...] + // a potentially-evaluated id-expression that denotes an immediate function. if (IsAddressOfFunction && getLangOpts().CPlusPlus20 && Specialization->isImmediateEscalating() && + parentEvaluationContext().isPotentiallyEvaluated() && CheckIfFunctionSpecializationIsImmediate(Specialization, Info.getLocation())) return TemplateDeductionResult::MiscellaneousDeductionFailure; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 07626058c7977..abb8a260faab9 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1619,11 +1619,6 @@ namespace { case TemplateArgument::Pack: // Literally rewrite the template argument pack, instead of unpacking // it. - assert( - SemaRef.CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::BuildingDeductionGuides && - "Transforming a template argument pack is only allowed in building " - "deduction guide"); for (auto &pack : Arg.getPackAsArray()) { TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc( pack, QualType(), SourceLocation{}); @@ -4375,9 +4370,9 @@ Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) { bool Sema::SubstTemplateArgument( const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateArgumentLoc &Output) { - TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(), - DeclarationName()); + TemplateArgumentLoc &Output, SourceLocation Loc, + const DeclarationName &Entity) { + TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity); return Instantiator.TransformTemplateArgument(Input, Output); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 381d79b2fcd46..bb49aae2cb666 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2956,11 +2956,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( } } if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { - TypeSourceInfo *InstantiatedDefaultArg = - SemaRef.SubstType(D->getDefaultArgumentInfo(), TemplateArgs, - D->getDefaultArgumentLoc(), D->getDeclName()); - if (InstantiatedDefaultArg) - Inst->setDefaultArgument(InstantiatedDefaultArg); + TemplateArgumentLoc Output; + if (!SemaRef.SubstTemplateArgument(D->getDefaultArgument(), TemplateArgs, + Output)) + Inst->setDefaultArgument(SemaRef.getASTContext(), Output); } // Introduce this template parameter's instantiation into the instantiation @@ -3124,9 +3123,10 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { EnterExpressionEvaluationContext ConstantEvaluated( SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - ExprResult Value = SemaRef.SubstExpr(D->getDefaultArgument(), TemplateArgs); - if (!Value.isInvalid()) - Param->setDefaultArgument(Value.get()); + TemplateArgumentLoc Result; + if (!SemaRef.SubstTemplateArgument(D->getDefaultArgument(), TemplateArgs, + Result)) + Param->setDefaultArgument(SemaRef.Context, Result); } // Introduce this template parameter's instantiation into the instantiation @@ -5055,6 +5055,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, Function->setLocation(PatternDecl->getLocation()); Function->setInnerLocStart(PatternDecl->getInnerLocStart()); Function->setRangeEnd(PatternDecl->getEndLoc()); + Function->setDeclarationNameLoc(PatternDecl->getNameInfo().getInfo()); EnterExpressionEvaluationContext EvalContext( *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 0b20604665068..7a44b978aacdb 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -66,6 +66,9 @@ namespace { bool shouldWalkTypesOfTypeLocs() const { return false; } + // We need this so we can find e.g. attributes on lambdas. + bool shouldVisitImplicitCode() const { return true; } + //------------------------------------------------------------------------ // Recording occurrences of (unexpanded) parameter packs. //------------------------------------------------------------------------ diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index c19c8cc34dd3b..ef0b6b701a52c 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -9345,9 +9345,9 @@ BuildTypeCoupledDecls(Expr *E, Decls.push_back(TypeCoupledDeclRefInfo(CountDecl, /*IsDref*/ false)); } -QualType Sema::BuildCountAttributedArrayType(QualType WrappedTy, - Expr *CountExpr) { - assert(WrappedTy->isIncompleteArrayType()); +QualType Sema::BuildCountAttributedArrayOrPointerType(QualType WrappedTy, + Expr *CountExpr) { + assert(WrappedTy->isIncompleteArrayType() || WrappedTy->isPointerType()); llvm::SmallVector Decls; BuildTypeCoupledDecls(CountExpr, Decls); diff --git a/clang/lib/Sema/SemaX86.cpp b/clang/lib/Sema/SemaX86.cpp new file mode 100644 index 0000000000000..ffac1afc5d782 --- /dev/null +++ b/clang/lib/Sema/SemaX86.cpp @@ -0,0 +1,878 @@ +//===------ SemaX86.cpp ---------- X86 target-specific routines -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements semantic analysis functions specific to X86. +// +//===----------------------------------------------------------------------===// + +#include "clang/Sema/SemaX86.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/TargetBuiltins.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/TargetParser/Triple.h" +#include + +namespace clang { + +SemaX86::SemaX86(Sema &S) : SemaBase(S) {} + +// Check if the rounding mode is legal. +bool SemaX86::CheckBuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { + // Indicates if this instruction has rounding control or just SAE. + bool HasRC = false; + + unsigned ArgNum = 0; + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_vcvttsd2si32: + case X86::BI__builtin_ia32_vcvttsd2si64: + case X86::BI__builtin_ia32_vcvttsd2usi32: + case X86::BI__builtin_ia32_vcvttsd2usi64: + case X86::BI__builtin_ia32_vcvttss2si32: + case X86::BI__builtin_ia32_vcvttss2si64: + case X86::BI__builtin_ia32_vcvttss2usi32: + case X86::BI__builtin_ia32_vcvttss2usi64: + case X86::BI__builtin_ia32_vcvttsh2si32: + case X86::BI__builtin_ia32_vcvttsh2si64: + case X86::BI__builtin_ia32_vcvttsh2usi32: + case X86::BI__builtin_ia32_vcvttsh2usi64: + ArgNum = 1; + break; + case X86::BI__builtin_ia32_maxpd512: + case X86::BI__builtin_ia32_maxps512: + case X86::BI__builtin_ia32_minpd512: + case X86::BI__builtin_ia32_minps512: + case X86::BI__builtin_ia32_maxph512: + case X86::BI__builtin_ia32_minph512: + ArgNum = 2; + break; + case X86::BI__builtin_ia32_vcvtph2pd512_mask: + case X86::BI__builtin_ia32_vcvtph2psx512_mask: + case X86::BI__builtin_ia32_cvtps2pd512_mask: + case X86::BI__builtin_ia32_cvttpd2dq512_mask: + case X86::BI__builtin_ia32_cvttpd2qq512_mask: + case X86::BI__builtin_ia32_cvttpd2udq512_mask: + case X86::BI__builtin_ia32_cvttpd2uqq512_mask: + case X86::BI__builtin_ia32_cvttps2dq512_mask: + case X86::BI__builtin_ia32_cvttps2qq512_mask: + case X86::BI__builtin_ia32_cvttps2udq512_mask: + case X86::BI__builtin_ia32_cvttps2uqq512_mask: + case X86::BI__builtin_ia32_vcvttph2w512_mask: + case X86::BI__builtin_ia32_vcvttph2uw512_mask: + case X86::BI__builtin_ia32_vcvttph2dq512_mask: + case X86::BI__builtin_ia32_vcvttph2udq512_mask: + case X86::BI__builtin_ia32_vcvttph2qq512_mask: + case X86::BI__builtin_ia32_vcvttph2uqq512_mask: + case X86::BI__builtin_ia32_getexppd512_mask: + case X86::BI__builtin_ia32_getexpps512_mask: + case X86::BI__builtin_ia32_getexpph512_mask: + case X86::BI__builtin_ia32_vcomisd: + case X86::BI__builtin_ia32_vcomiss: + case X86::BI__builtin_ia32_vcomish: + case X86::BI__builtin_ia32_vcvtph2ps512_mask: + ArgNum = 3; + break; + case X86::BI__builtin_ia32_cmppd512_mask: + case X86::BI__builtin_ia32_cmpps512_mask: + case X86::BI__builtin_ia32_cmpsd_mask: + case X86::BI__builtin_ia32_cmpss_mask: + case X86::BI__builtin_ia32_cmpsh_mask: + case X86::BI__builtin_ia32_vcvtsh2sd_round_mask: + case X86::BI__builtin_ia32_vcvtsh2ss_round_mask: + case X86::BI__builtin_ia32_cvtss2sd_round_mask: + case X86::BI__builtin_ia32_getexpsd128_round_mask: + case X86::BI__builtin_ia32_getexpss128_round_mask: + case X86::BI__builtin_ia32_getexpsh128_round_mask: + case X86::BI__builtin_ia32_getmantpd512_mask: + case X86::BI__builtin_ia32_getmantps512_mask: + case X86::BI__builtin_ia32_getmantph512_mask: + case X86::BI__builtin_ia32_maxsd_round_mask: + case X86::BI__builtin_ia32_maxss_round_mask: + case X86::BI__builtin_ia32_maxsh_round_mask: + case X86::BI__builtin_ia32_minsd_round_mask: + case X86::BI__builtin_ia32_minss_round_mask: + case X86::BI__builtin_ia32_minsh_round_mask: + case X86::BI__builtin_ia32_reducepd512_mask: + case X86::BI__builtin_ia32_reduceps512_mask: + case X86::BI__builtin_ia32_reduceph512_mask: + case X86::BI__builtin_ia32_rndscalepd_mask: + case X86::BI__builtin_ia32_rndscaleps_mask: + case X86::BI__builtin_ia32_rndscaleph_mask: + ArgNum = 4; + break; + case X86::BI__builtin_ia32_fixupimmpd512_mask: + case X86::BI__builtin_ia32_fixupimmpd512_maskz: + case X86::BI__builtin_ia32_fixupimmps512_mask: + case X86::BI__builtin_ia32_fixupimmps512_maskz: + case X86::BI__builtin_ia32_fixupimmsd_mask: + case X86::BI__builtin_ia32_fixupimmsd_maskz: + case X86::BI__builtin_ia32_fixupimmss_mask: + case X86::BI__builtin_ia32_fixupimmss_maskz: + case X86::BI__builtin_ia32_getmantsd_round_mask: + case X86::BI__builtin_ia32_getmantss_round_mask: + case X86::BI__builtin_ia32_getmantsh_round_mask: + case X86::BI__builtin_ia32_rangepd512_mask: + case X86::BI__builtin_ia32_rangeps512_mask: + case X86::BI__builtin_ia32_rangesd128_round_mask: + case X86::BI__builtin_ia32_rangess128_round_mask: + case X86::BI__builtin_ia32_reducesd_mask: + case X86::BI__builtin_ia32_reducess_mask: + case X86::BI__builtin_ia32_reducesh_mask: + case X86::BI__builtin_ia32_rndscalesd_round_mask: + case X86::BI__builtin_ia32_rndscaless_round_mask: + case X86::BI__builtin_ia32_rndscalesh_round_mask: + ArgNum = 5; + break; + case X86::BI__builtin_ia32_vcvtsd2si64: + case X86::BI__builtin_ia32_vcvtsd2si32: + case X86::BI__builtin_ia32_vcvtsd2usi32: + case X86::BI__builtin_ia32_vcvtsd2usi64: + case X86::BI__builtin_ia32_vcvtss2si32: + case X86::BI__builtin_ia32_vcvtss2si64: + case X86::BI__builtin_ia32_vcvtss2usi32: + case X86::BI__builtin_ia32_vcvtss2usi64: + case X86::BI__builtin_ia32_vcvtsh2si32: + case X86::BI__builtin_ia32_vcvtsh2si64: + case X86::BI__builtin_ia32_vcvtsh2usi32: + case X86::BI__builtin_ia32_vcvtsh2usi64: + case X86::BI__builtin_ia32_sqrtpd512: + case X86::BI__builtin_ia32_sqrtps512: + case X86::BI__builtin_ia32_sqrtph512: + ArgNum = 1; + HasRC = true; + break; + case X86::BI__builtin_ia32_addph512: + case X86::BI__builtin_ia32_divph512: + case X86::BI__builtin_ia32_mulph512: + case X86::BI__builtin_ia32_subph512: + case X86::BI__builtin_ia32_addpd512: + case X86::BI__builtin_ia32_addps512: + case X86::BI__builtin_ia32_divpd512: + case X86::BI__builtin_ia32_divps512: + case X86::BI__builtin_ia32_mulpd512: + case X86::BI__builtin_ia32_mulps512: + case X86::BI__builtin_ia32_subpd512: + case X86::BI__builtin_ia32_subps512: + case X86::BI__builtin_ia32_cvtsi2sd64: + case X86::BI__builtin_ia32_cvtsi2ss32: + case X86::BI__builtin_ia32_cvtsi2ss64: + case X86::BI__builtin_ia32_cvtusi2sd64: + case X86::BI__builtin_ia32_cvtusi2ss32: + case X86::BI__builtin_ia32_cvtusi2ss64: + case X86::BI__builtin_ia32_vcvtusi2sh: + case X86::BI__builtin_ia32_vcvtusi642sh: + case X86::BI__builtin_ia32_vcvtsi2sh: + case X86::BI__builtin_ia32_vcvtsi642sh: + ArgNum = 2; + HasRC = true; + break; + case X86::BI__builtin_ia32_cvtdq2ps512_mask: + case X86::BI__builtin_ia32_cvtudq2ps512_mask: + case X86::BI__builtin_ia32_vcvtpd2ph512_mask: + case X86::BI__builtin_ia32_vcvtps2phx512_mask: + case X86::BI__builtin_ia32_cvtpd2ps512_mask: + case X86::BI__builtin_ia32_cvtpd2dq512_mask: + case X86::BI__builtin_ia32_cvtpd2qq512_mask: + case X86::BI__builtin_ia32_cvtpd2udq512_mask: + case X86::BI__builtin_ia32_cvtpd2uqq512_mask: + case X86::BI__builtin_ia32_cvtps2dq512_mask: + case X86::BI__builtin_ia32_cvtps2qq512_mask: + case X86::BI__builtin_ia32_cvtps2udq512_mask: + case X86::BI__builtin_ia32_cvtps2uqq512_mask: + case X86::BI__builtin_ia32_cvtqq2pd512_mask: + case X86::BI__builtin_ia32_cvtqq2ps512_mask: + case X86::BI__builtin_ia32_cvtuqq2pd512_mask: + case X86::BI__builtin_ia32_cvtuqq2ps512_mask: + case X86::BI__builtin_ia32_vcvtdq2ph512_mask: + case X86::BI__builtin_ia32_vcvtudq2ph512_mask: + case X86::BI__builtin_ia32_vcvtw2ph512_mask: + case X86::BI__builtin_ia32_vcvtuw2ph512_mask: + case X86::BI__builtin_ia32_vcvtph2w512_mask: + case X86::BI__builtin_ia32_vcvtph2uw512_mask: + case X86::BI__builtin_ia32_vcvtph2dq512_mask: + case X86::BI__builtin_ia32_vcvtph2udq512_mask: + case X86::BI__builtin_ia32_vcvtph2qq512_mask: + case X86::BI__builtin_ia32_vcvtph2uqq512_mask: + case X86::BI__builtin_ia32_vcvtqq2ph512_mask: + case X86::BI__builtin_ia32_vcvtuqq2ph512_mask: + ArgNum = 3; + HasRC = true; + break; + case X86::BI__builtin_ia32_addsh_round_mask: + case X86::BI__builtin_ia32_addss_round_mask: + case X86::BI__builtin_ia32_addsd_round_mask: + case X86::BI__builtin_ia32_divsh_round_mask: + case X86::BI__builtin_ia32_divss_round_mask: + case X86::BI__builtin_ia32_divsd_round_mask: + case X86::BI__builtin_ia32_mulsh_round_mask: + case X86::BI__builtin_ia32_mulss_round_mask: + case X86::BI__builtin_ia32_mulsd_round_mask: + case X86::BI__builtin_ia32_subsh_round_mask: + case X86::BI__builtin_ia32_subss_round_mask: + case X86::BI__builtin_ia32_subsd_round_mask: + case X86::BI__builtin_ia32_scalefph512_mask: + case X86::BI__builtin_ia32_scalefpd512_mask: + case X86::BI__builtin_ia32_scalefps512_mask: + case X86::BI__builtin_ia32_scalefsd_round_mask: + case X86::BI__builtin_ia32_scalefss_round_mask: + case X86::BI__builtin_ia32_scalefsh_round_mask: + case X86::BI__builtin_ia32_cvtsd2ss_round_mask: + case X86::BI__builtin_ia32_vcvtss2sh_round_mask: + case X86::BI__builtin_ia32_vcvtsd2sh_round_mask: + case X86::BI__builtin_ia32_sqrtsd_round_mask: + case X86::BI__builtin_ia32_sqrtss_round_mask: + case X86::BI__builtin_ia32_sqrtsh_round_mask: + case X86::BI__builtin_ia32_vfmaddsd3_mask: + case X86::BI__builtin_ia32_vfmaddsd3_maskz: + case X86::BI__builtin_ia32_vfmaddsd3_mask3: + case X86::BI__builtin_ia32_vfmaddss3_mask: + case X86::BI__builtin_ia32_vfmaddss3_maskz: + case X86::BI__builtin_ia32_vfmaddss3_mask3: + case X86::BI__builtin_ia32_vfmaddsh3_mask: + case X86::BI__builtin_ia32_vfmaddsh3_maskz: + case X86::BI__builtin_ia32_vfmaddsh3_mask3: + case X86::BI__builtin_ia32_vfmaddpd512_mask: + case X86::BI__builtin_ia32_vfmaddpd512_maskz: + case X86::BI__builtin_ia32_vfmaddpd512_mask3: + case X86::BI__builtin_ia32_vfmsubpd512_mask3: + case X86::BI__builtin_ia32_vfmaddps512_mask: + case X86::BI__builtin_ia32_vfmaddps512_maskz: + case X86::BI__builtin_ia32_vfmaddps512_mask3: + case X86::BI__builtin_ia32_vfmsubps512_mask3: + case X86::BI__builtin_ia32_vfmaddph512_mask: + case X86::BI__builtin_ia32_vfmaddph512_maskz: + case X86::BI__builtin_ia32_vfmaddph512_mask3: + case X86::BI__builtin_ia32_vfmsubph512_mask3: + case X86::BI__builtin_ia32_vfmaddsubpd512_mask: + case X86::BI__builtin_ia32_vfmaddsubpd512_maskz: + case X86::BI__builtin_ia32_vfmaddsubpd512_mask3: + case X86::BI__builtin_ia32_vfmsubaddpd512_mask3: + case X86::BI__builtin_ia32_vfmaddsubps512_mask: + case X86::BI__builtin_ia32_vfmaddsubps512_maskz: + case X86::BI__builtin_ia32_vfmaddsubps512_mask3: + case X86::BI__builtin_ia32_vfmsubaddps512_mask3: + case X86::BI__builtin_ia32_vfmaddsubph512_mask: + case X86::BI__builtin_ia32_vfmaddsubph512_maskz: + case X86::BI__builtin_ia32_vfmaddsubph512_mask3: + case X86::BI__builtin_ia32_vfmsubaddph512_mask3: + case X86::BI__builtin_ia32_vfmaddcsh_mask: + case X86::BI__builtin_ia32_vfmaddcsh_round_mask: + case X86::BI__builtin_ia32_vfmaddcsh_round_mask3: + case X86::BI__builtin_ia32_vfmaddcph512_mask: + case X86::BI__builtin_ia32_vfmaddcph512_maskz: + case X86::BI__builtin_ia32_vfmaddcph512_mask3: + case X86::BI__builtin_ia32_vfcmaddcsh_mask: + case X86::BI__builtin_ia32_vfcmaddcsh_round_mask: + case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3: + case X86::BI__builtin_ia32_vfcmaddcph512_mask: + case X86::BI__builtin_ia32_vfcmaddcph512_maskz: + case X86::BI__builtin_ia32_vfcmaddcph512_mask3: + case X86::BI__builtin_ia32_vfmulcsh_mask: + case X86::BI__builtin_ia32_vfmulcph512_mask: + case X86::BI__builtin_ia32_vfcmulcsh_mask: + case X86::BI__builtin_ia32_vfcmulcph512_mask: + ArgNum = 4; + HasRC = true; + break; + } + + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + // Make sure rounding mode is either ROUND_CUR_DIRECTION or ROUND_NO_EXC bit + // is set. If the intrinsic has rounding control(bits 1:0), make sure its only + // combined with ROUND_NO_EXC. If the intrinsic does not have rounding + // control, allow ROUND_NO_EXC and ROUND_CUR_DIRECTION together. + if (Result == 4 /*ROUND_CUR_DIRECTION*/ || Result == 8 /*ROUND_NO_EXC*/ || + (!HasRC && Result == 12 /*ROUND_CUR_DIRECTION|ROUND_NO_EXC*/) || + (HasRC && Result.getZExtValue() >= 8 && Result.getZExtValue() <= 11)) + return false; + + return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_rounding) + << Arg->getSourceRange(); +} + +// Check if the gather/scatter scale is legal. +bool SemaX86::CheckBuiltinGatherScatterScale(unsigned BuiltinID, + CallExpr *TheCall) { + unsigned ArgNum = 0; + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_gatherd_pd: + case X86::BI__builtin_ia32_gatherd_pd256: + case X86::BI__builtin_ia32_gatherq_pd: + case X86::BI__builtin_ia32_gatherq_pd256: + case X86::BI__builtin_ia32_gatherd_ps: + case X86::BI__builtin_ia32_gatherd_ps256: + case X86::BI__builtin_ia32_gatherq_ps: + case X86::BI__builtin_ia32_gatherq_ps256: + case X86::BI__builtin_ia32_gatherd_q: + case X86::BI__builtin_ia32_gatherd_q256: + case X86::BI__builtin_ia32_gatherq_q: + case X86::BI__builtin_ia32_gatherq_q256: + case X86::BI__builtin_ia32_gatherd_d: + case X86::BI__builtin_ia32_gatherd_d256: + case X86::BI__builtin_ia32_gatherq_d: + case X86::BI__builtin_ia32_gatherq_d256: + case X86::BI__builtin_ia32_gather3div2df: + case X86::BI__builtin_ia32_gather3div2di: + case X86::BI__builtin_ia32_gather3div4df: + case X86::BI__builtin_ia32_gather3div4di: + case X86::BI__builtin_ia32_gather3div4sf: + case X86::BI__builtin_ia32_gather3div4si: + case X86::BI__builtin_ia32_gather3div8sf: + case X86::BI__builtin_ia32_gather3div8si: + case X86::BI__builtin_ia32_gather3siv2df: + case X86::BI__builtin_ia32_gather3siv2di: + case X86::BI__builtin_ia32_gather3siv4df: + case X86::BI__builtin_ia32_gather3siv4di: + case X86::BI__builtin_ia32_gather3siv4sf: + case X86::BI__builtin_ia32_gather3siv4si: + case X86::BI__builtin_ia32_gather3siv8sf: + case X86::BI__builtin_ia32_gather3siv8si: + case X86::BI__builtin_ia32_gathersiv8df: + case X86::BI__builtin_ia32_gathersiv16sf: + case X86::BI__builtin_ia32_gatherdiv8df: + case X86::BI__builtin_ia32_gatherdiv16sf: + case X86::BI__builtin_ia32_gathersiv8di: + case X86::BI__builtin_ia32_gathersiv16si: + case X86::BI__builtin_ia32_gatherdiv8di: + case X86::BI__builtin_ia32_gatherdiv16si: + case X86::BI__builtin_ia32_scatterdiv2df: + case X86::BI__builtin_ia32_scatterdiv2di: + case X86::BI__builtin_ia32_scatterdiv4df: + case X86::BI__builtin_ia32_scatterdiv4di: + case X86::BI__builtin_ia32_scatterdiv4sf: + case X86::BI__builtin_ia32_scatterdiv4si: + case X86::BI__builtin_ia32_scatterdiv8sf: + case X86::BI__builtin_ia32_scatterdiv8si: + case X86::BI__builtin_ia32_scattersiv2df: + case X86::BI__builtin_ia32_scattersiv2di: + case X86::BI__builtin_ia32_scattersiv4df: + case X86::BI__builtin_ia32_scattersiv4di: + case X86::BI__builtin_ia32_scattersiv4sf: + case X86::BI__builtin_ia32_scattersiv4si: + case X86::BI__builtin_ia32_scattersiv8sf: + case X86::BI__builtin_ia32_scattersiv8si: + case X86::BI__builtin_ia32_scattersiv8df: + case X86::BI__builtin_ia32_scattersiv16sf: + case X86::BI__builtin_ia32_scatterdiv8df: + case X86::BI__builtin_ia32_scatterdiv16sf: + case X86::BI__builtin_ia32_scattersiv8di: + case X86::BI__builtin_ia32_scattersiv16si: + case X86::BI__builtin_ia32_scatterdiv8di: + case X86::BI__builtin_ia32_scatterdiv16si: + ArgNum = 4; + break; + } + + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + if (Result == 1 || Result == 2 || Result == 4 || Result == 8) + return false; + + return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_scale) + << Arg->getSourceRange(); +} + +enum { TileRegLow = 0, TileRegHigh = 7 }; + +bool SemaX86::CheckBuiltinTileArgumentsRange(CallExpr *TheCall, + ArrayRef ArgNums) { + for (int ArgNum : ArgNums) { + if (SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, TileRegLow, + TileRegHigh)) + return true; + } + return false; +} + +bool SemaX86::CheckBuiltinTileDuplicate(CallExpr *TheCall, + ArrayRef ArgNums) { + // Because the max number of tile register is TileRegHigh + 1, so here we use + // each bit to represent the usage of them in bitset. + std::bitset ArgValues; + for (int ArgNum : ArgNums) { + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + continue; + + llvm::APSInt Result; + if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + int ArgExtValue = Result.getExtValue(); + assert((ArgExtValue >= TileRegLow && ArgExtValue <= TileRegHigh) && + "Incorrect tile register num."); + if (ArgValues.test(ArgExtValue)) + return Diag(TheCall->getBeginLoc(), + diag::err_x86_builtin_tile_arg_duplicate) + << TheCall->getArg(ArgNum)->getSourceRange(); + ArgValues.set(ArgExtValue); + } + return false; +} + +bool SemaX86::CheckBuiltinTileRangeAndDuplicate(CallExpr *TheCall, + ArrayRef ArgNums) { + return CheckBuiltinTileArgumentsRange(TheCall, ArgNums) || + CheckBuiltinTileDuplicate(TheCall, ArgNums); +} + +bool SemaX86::CheckBuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall) { + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_tileloadd64: + case X86::BI__builtin_ia32_tileloaddt164: + case X86::BI__builtin_ia32_tilestored64: + case X86::BI__builtin_ia32_tilezero: + return CheckBuiltinTileArgumentsRange(TheCall, 0); + case X86::BI__builtin_ia32_tdpbssd: + case X86::BI__builtin_ia32_tdpbsud: + case X86::BI__builtin_ia32_tdpbusd: + case X86::BI__builtin_ia32_tdpbuud: + case X86::BI__builtin_ia32_tdpbf16ps: + case X86::BI__builtin_ia32_tdpfp16ps: + case X86::BI__builtin_ia32_tcmmimfp16ps: + case X86::BI__builtin_ia32_tcmmrlfp16ps: + return CheckBuiltinTileRangeAndDuplicate(TheCall, {0, 1, 2}); + } +} +static bool isX86_32Builtin(unsigned BuiltinID) { + // These builtins only work on x86-32 targets. + switch (BuiltinID) { + case X86::BI__builtin_ia32_readeflags_u32: + case X86::BI__builtin_ia32_writeeflags_u32: + return true; + } + + return false; +} + +bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall) { + // Check for 32-bit only builtins on a 64-bit target. + const llvm::Triple &TT = TI.getTriple(); + if (TT.getArch() != llvm::Triple::x86 && isX86_32Builtin(BuiltinID)) + return Diag(TheCall->getCallee()->getBeginLoc(), + diag::err_32_bit_builtin_64_bit_tgt); + + // If the intrinsic has rounding or SAE make sure its valid. + if (CheckBuiltinRoundingOrSAE(BuiltinID, TheCall)) + return true; + + // If the intrinsic has a gather/scatter scale immediate make sure its valid. + if (CheckBuiltinGatherScatterScale(BuiltinID, TheCall)) + return true; + + // If the intrinsic has a tile arguments, make sure they are valid. + if (CheckBuiltinTileArguments(BuiltinID, TheCall)) + return true; + + // For intrinsics which take an immediate value as part of the instruction, + // range check them here. + int i = 0, l = 0, u = 0; + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_vec_ext_v2si: + case X86::BI__builtin_ia32_vec_ext_v2di: + case X86::BI__builtin_ia32_vextractf128_pd256: + case X86::BI__builtin_ia32_vextractf128_ps256: + case X86::BI__builtin_ia32_vextractf128_si256: + case X86::BI__builtin_ia32_extract128i256: + case X86::BI__builtin_ia32_extractf64x4_mask: + case X86::BI__builtin_ia32_extracti64x4_mask: + case X86::BI__builtin_ia32_extractf32x8_mask: + case X86::BI__builtin_ia32_extracti32x8_mask: + case X86::BI__builtin_ia32_extractf64x2_256_mask: + case X86::BI__builtin_ia32_extracti64x2_256_mask: + case X86::BI__builtin_ia32_extractf32x4_256_mask: + case X86::BI__builtin_ia32_extracti32x4_256_mask: + i = 1; + l = 0; + u = 1; + break; + case X86::BI__builtin_ia32_vec_set_v2di: + case X86::BI__builtin_ia32_vinsertf128_pd256: + case X86::BI__builtin_ia32_vinsertf128_ps256: + case X86::BI__builtin_ia32_vinsertf128_si256: + case X86::BI__builtin_ia32_insert128i256: + case X86::BI__builtin_ia32_insertf32x8: + case X86::BI__builtin_ia32_inserti32x8: + case X86::BI__builtin_ia32_insertf64x4: + case X86::BI__builtin_ia32_inserti64x4: + case X86::BI__builtin_ia32_insertf64x2_256: + case X86::BI__builtin_ia32_inserti64x2_256: + case X86::BI__builtin_ia32_insertf32x4_256: + case X86::BI__builtin_ia32_inserti32x4_256: + i = 2; + l = 0; + u = 1; + break; + case X86::BI__builtin_ia32_vpermilpd: + case X86::BI__builtin_ia32_vec_ext_v4hi: + case X86::BI__builtin_ia32_vec_ext_v4si: + case X86::BI__builtin_ia32_vec_ext_v4sf: + case X86::BI__builtin_ia32_vec_ext_v4di: + case X86::BI__builtin_ia32_extractf32x4_mask: + case X86::BI__builtin_ia32_extracti32x4_mask: + case X86::BI__builtin_ia32_extractf64x2_512_mask: + case X86::BI__builtin_ia32_extracti64x2_512_mask: + i = 1; + l = 0; + u = 3; + break; + case X86::BI_mm_prefetch: + case X86::BI__builtin_ia32_vec_ext_v8hi: + case X86::BI__builtin_ia32_vec_ext_v8si: + i = 1; + l = 0; + u = 7; + break; + case X86::BI__builtin_ia32_sha1rnds4: + case X86::BI__builtin_ia32_blendpd: + case X86::BI__builtin_ia32_shufpd: + case X86::BI__builtin_ia32_vec_set_v4hi: + case X86::BI__builtin_ia32_vec_set_v4si: + case X86::BI__builtin_ia32_vec_set_v4di: + case X86::BI__builtin_ia32_shuf_f32x4_256: + case X86::BI__builtin_ia32_shuf_f64x2_256: + case X86::BI__builtin_ia32_shuf_i32x4_256: + case X86::BI__builtin_ia32_shuf_i64x2_256: + case X86::BI__builtin_ia32_insertf64x2_512: + case X86::BI__builtin_ia32_inserti64x2_512: + case X86::BI__builtin_ia32_insertf32x4: + case X86::BI__builtin_ia32_inserti32x4: + i = 2; + l = 0; + u = 3; + break; + case X86::BI__builtin_ia32_vpermil2pd: + case X86::BI__builtin_ia32_vpermil2pd256: + case X86::BI__builtin_ia32_vpermil2ps: + case X86::BI__builtin_ia32_vpermil2ps256: + i = 3; + l = 0; + u = 3; + break; + case X86::BI__builtin_ia32_cmpb128_mask: + case X86::BI__builtin_ia32_cmpw128_mask: + case X86::BI__builtin_ia32_cmpd128_mask: + case X86::BI__builtin_ia32_cmpq128_mask: + case X86::BI__builtin_ia32_cmpb256_mask: + case X86::BI__builtin_ia32_cmpw256_mask: + case X86::BI__builtin_ia32_cmpd256_mask: + case X86::BI__builtin_ia32_cmpq256_mask: + case X86::BI__builtin_ia32_cmpb512_mask: + case X86::BI__builtin_ia32_cmpw512_mask: + case X86::BI__builtin_ia32_cmpd512_mask: + case X86::BI__builtin_ia32_cmpq512_mask: + case X86::BI__builtin_ia32_ucmpb128_mask: + case X86::BI__builtin_ia32_ucmpw128_mask: + case X86::BI__builtin_ia32_ucmpd128_mask: + case X86::BI__builtin_ia32_ucmpq128_mask: + case X86::BI__builtin_ia32_ucmpb256_mask: + case X86::BI__builtin_ia32_ucmpw256_mask: + case X86::BI__builtin_ia32_ucmpd256_mask: + case X86::BI__builtin_ia32_ucmpq256_mask: + case X86::BI__builtin_ia32_ucmpb512_mask: + case X86::BI__builtin_ia32_ucmpw512_mask: + case X86::BI__builtin_ia32_ucmpd512_mask: + case X86::BI__builtin_ia32_ucmpq512_mask: + case X86::BI__builtin_ia32_vpcomub: + case X86::BI__builtin_ia32_vpcomuw: + case X86::BI__builtin_ia32_vpcomud: + case X86::BI__builtin_ia32_vpcomuq: + case X86::BI__builtin_ia32_vpcomb: + case X86::BI__builtin_ia32_vpcomw: + case X86::BI__builtin_ia32_vpcomd: + case X86::BI__builtin_ia32_vpcomq: + case X86::BI__builtin_ia32_vec_set_v8hi: + case X86::BI__builtin_ia32_vec_set_v8si: + i = 2; + l = 0; + u = 7; + break; + case X86::BI__builtin_ia32_vpermilpd256: + case X86::BI__builtin_ia32_roundps: + case X86::BI__builtin_ia32_roundpd: + case X86::BI__builtin_ia32_roundps256: + case X86::BI__builtin_ia32_roundpd256: + case X86::BI__builtin_ia32_getmantpd128_mask: + case X86::BI__builtin_ia32_getmantpd256_mask: + case X86::BI__builtin_ia32_getmantps128_mask: + case X86::BI__builtin_ia32_getmantps256_mask: + case X86::BI__builtin_ia32_getmantpd512_mask: + case X86::BI__builtin_ia32_getmantps512_mask: + case X86::BI__builtin_ia32_getmantph128_mask: + case X86::BI__builtin_ia32_getmantph256_mask: + case X86::BI__builtin_ia32_getmantph512_mask: + case X86::BI__builtin_ia32_vec_ext_v16qi: + case X86::BI__builtin_ia32_vec_ext_v16hi: + i = 1; + l = 0; + u = 15; + break; + case X86::BI__builtin_ia32_pblendd128: + case X86::BI__builtin_ia32_blendps: + case X86::BI__builtin_ia32_blendpd256: + case X86::BI__builtin_ia32_shufpd256: + case X86::BI__builtin_ia32_roundss: + case X86::BI__builtin_ia32_roundsd: + case X86::BI__builtin_ia32_rangepd128_mask: + case X86::BI__builtin_ia32_rangepd256_mask: + case X86::BI__builtin_ia32_rangepd512_mask: + case X86::BI__builtin_ia32_rangeps128_mask: + case X86::BI__builtin_ia32_rangeps256_mask: + case X86::BI__builtin_ia32_rangeps512_mask: + case X86::BI__builtin_ia32_getmantsd_round_mask: + case X86::BI__builtin_ia32_getmantss_round_mask: + case X86::BI__builtin_ia32_getmantsh_round_mask: + case X86::BI__builtin_ia32_vec_set_v16qi: + case X86::BI__builtin_ia32_vec_set_v16hi: + i = 2; + l = 0; + u = 15; + break; + case X86::BI__builtin_ia32_vec_ext_v32qi: + i = 1; + l = 0; + u = 31; + break; + case X86::BI__builtin_ia32_cmpps: + case X86::BI__builtin_ia32_cmpss: + case X86::BI__builtin_ia32_cmppd: + case X86::BI__builtin_ia32_cmpsd: + case X86::BI__builtin_ia32_cmpps256: + case X86::BI__builtin_ia32_cmppd256: + case X86::BI__builtin_ia32_cmpps128_mask: + case X86::BI__builtin_ia32_cmppd128_mask: + case X86::BI__builtin_ia32_cmpps256_mask: + case X86::BI__builtin_ia32_cmppd256_mask: + case X86::BI__builtin_ia32_cmpps512_mask: + case X86::BI__builtin_ia32_cmppd512_mask: + case X86::BI__builtin_ia32_cmpsd_mask: + case X86::BI__builtin_ia32_cmpss_mask: + case X86::BI__builtin_ia32_vec_set_v32qi: + i = 2; + l = 0; + u = 31; + break; + case X86::BI__builtin_ia32_permdf256: + case X86::BI__builtin_ia32_permdi256: + case X86::BI__builtin_ia32_permdf512: + case X86::BI__builtin_ia32_permdi512: + case X86::BI__builtin_ia32_vpermilps: + case X86::BI__builtin_ia32_vpermilps256: + case X86::BI__builtin_ia32_vpermilpd512: + case X86::BI__builtin_ia32_vpermilps512: + case X86::BI__builtin_ia32_pshufd: + case X86::BI__builtin_ia32_pshufd256: + case X86::BI__builtin_ia32_pshufd512: + case X86::BI__builtin_ia32_pshufhw: + case X86::BI__builtin_ia32_pshufhw256: + case X86::BI__builtin_ia32_pshufhw512: + case X86::BI__builtin_ia32_pshuflw: + case X86::BI__builtin_ia32_pshuflw256: + case X86::BI__builtin_ia32_pshuflw512: + case X86::BI__builtin_ia32_vcvtps2ph: + case X86::BI__builtin_ia32_vcvtps2ph_mask: + case X86::BI__builtin_ia32_vcvtps2ph256: + case X86::BI__builtin_ia32_vcvtps2ph256_mask: + case X86::BI__builtin_ia32_vcvtps2ph512_mask: + case X86::BI__builtin_ia32_rndscaleps_128_mask: + case X86::BI__builtin_ia32_rndscalepd_128_mask: + case X86::BI__builtin_ia32_rndscaleps_256_mask: + case X86::BI__builtin_ia32_rndscalepd_256_mask: + case X86::BI__builtin_ia32_rndscaleps_mask: + case X86::BI__builtin_ia32_rndscalepd_mask: + case X86::BI__builtin_ia32_rndscaleph_mask: + case X86::BI__builtin_ia32_reducepd128_mask: + case X86::BI__builtin_ia32_reducepd256_mask: + case X86::BI__builtin_ia32_reducepd512_mask: + case X86::BI__builtin_ia32_reduceps128_mask: + case X86::BI__builtin_ia32_reduceps256_mask: + case X86::BI__builtin_ia32_reduceps512_mask: + case X86::BI__builtin_ia32_reduceph128_mask: + case X86::BI__builtin_ia32_reduceph256_mask: + case X86::BI__builtin_ia32_reduceph512_mask: + case X86::BI__builtin_ia32_prold512: + case X86::BI__builtin_ia32_prolq512: + case X86::BI__builtin_ia32_prold128: + case X86::BI__builtin_ia32_prold256: + case X86::BI__builtin_ia32_prolq128: + case X86::BI__builtin_ia32_prolq256: + case X86::BI__builtin_ia32_prord512: + case X86::BI__builtin_ia32_prorq512: + case X86::BI__builtin_ia32_prord128: + case X86::BI__builtin_ia32_prord256: + case X86::BI__builtin_ia32_prorq128: + case X86::BI__builtin_ia32_prorq256: + case X86::BI__builtin_ia32_fpclasspd128_mask: + case X86::BI__builtin_ia32_fpclasspd256_mask: + case X86::BI__builtin_ia32_fpclassps128_mask: + case X86::BI__builtin_ia32_fpclassps256_mask: + case X86::BI__builtin_ia32_fpclassps512_mask: + case X86::BI__builtin_ia32_fpclasspd512_mask: + case X86::BI__builtin_ia32_fpclassph128_mask: + case X86::BI__builtin_ia32_fpclassph256_mask: + case X86::BI__builtin_ia32_fpclassph512_mask: + case X86::BI__builtin_ia32_fpclasssd_mask: + case X86::BI__builtin_ia32_fpclassss_mask: + case X86::BI__builtin_ia32_fpclasssh_mask: + case X86::BI__builtin_ia32_pslldqi128_byteshift: + case X86::BI__builtin_ia32_pslldqi256_byteshift: + case X86::BI__builtin_ia32_pslldqi512_byteshift: + case X86::BI__builtin_ia32_psrldqi128_byteshift: + case X86::BI__builtin_ia32_psrldqi256_byteshift: + case X86::BI__builtin_ia32_psrldqi512_byteshift: + case X86::BI__builtin_ia32_kshiftliqi: + case X86::BI__builtin_ia32_kshiftlihi: + case X86::BI__builtin_ia32_kshiftlisi: + case X86::BI__builtin_ia32_kshiftlidi: + case X86::BI__builtin_ia32_kshiftriqi: + case X86::BI__builtin_ia32_kshiftrihi: + case X86::BI__builtin_ia32_kshiftrisi: + case X86::BI__builtin_ia32_kshiftridi: + i = 1; + l = 0; + u = 255; + break; + case X86::BI__builtin_ia32_vperm2f128_pd256: + case X86::BI__builtin_ia32_vperm2f128_ps256: + case X86::BI__builtin_ia32_vperm2f128_si256: + case X86::BI__builtin_ia32_permti256: + case X86::BI__builtin_ia32_pblendw128: + case X86::BI__builtin_ia32_pblendw256: + case X86::BI__builtin_ia32_blendps256: + case X86::BI__builtin_ia32_pblendd256: + case X86::BI__builtin_ia32_palignr128: + case X86::BI__builtin_ia32_palignr256: + case X86::BI__builtin_ia32_palignr512: + case X86::BI__builtin_ia32_alignq512: + case X86::BI__builtin_ia32_alignd512: + case X86::BI__builtin_ia32_alignd128: + case X86::BI__builtin_ia32_alignd256: + case X86::BI__builtin_ia32_alignq128: + case X86::BI__builtin_ia32_alignq256: + case X86::BI__builtin_ia32_vcomisd: + case X86::BI__builtin_ia32_vcomiss: + case X86::BI__builtin_ia32_shuf_f32x4: + case X86::BI__builtin_ia32_shuf_f64x2: + case X86::BI__builtin_ia32_shuf_i32x4: + case X86::BI__builtin_ia32_shuf_i64x2: + case X86::BI__builtin_ia32_shufpd512: + case X86::BI__builtin_ia32_shufps: + case X86::BI__builtin_ia32_shufps256: + case X86::BI__builtin_ia32_shufps512: + case X86::BI__builtin_ia32_dbpsadbw128: + case X86::BI__builtin_ia32_dbpsadbw256: + case X86::BI__builtin_ia32_dbpsadbw512: + case X86::BI__builtin_ia32_vpshldd128: + case X86::BI__builtin_ia32_vpshldd256: + case X86::BI__builtin_ia32_vpshldd512: + case X86::BI__builtin_ia32_vpshldq128: + case X86::BI__builtin_ia32_vpshldq256: + case X86::BI__builtin_ia32_vpshldq512: + case X86::BI__builtin_ia32_vpshldw128: + case X86::BI__builtin_ia32_vpshldw256: + case X86::BI__builtin_ia32_vpshldw512: + case X86::BI__builtin_ia32_vpshrdd128: + case X86::BI__builtin_ia32_vpshrdd256: + case X86::BI__builtin_ia32_vpshrdd512: + case X86::BI__builtin_ia32_vpshrdq128: + case X86::BI__builtin_ia32_vpshrdq256: + case X86::BI__builtin_ia32_vpshrdq512: + case X86::BI__builtin_ia32_vpshrdw128: + case X86::BI__builtin_ia32_vpshrdw256: + case X86::BI__builtin_ia32_vpshrdw512: + i = 2; + l = 0; + u = 255; + break; + case X86::BI__builtin_ia32_fixupimmpd512_mask: + case X86::BI__builtin_ia32_fixupimmpd512_maskz: + case X86::BI__builtin_ia32_fixupimmps512_mask: + case X86::BI__builtin_ia32_fixupimmps512_maskz: + case X86::BI__builtin_ia32_fixupimmsd_mask: + case X86::BI__builtin_ia32_fixupimmsd_maskz: + case X86::BI__builtin_ia32_fixupimmss_mask: + case X86::BI__builtin_ia32_fixupimmss_maskz: + case X86::BI__builtin_ia32_fixupimmpd128_mask: + case X86::BI__builtin_ia32_fixupimmpd128_maskz: + case X86::BI__builtin_ia32_fixupimmpd256_mask: + case X86::BI__builtin_ia32_fixupimmpd256_maskz: + case X86::BI__builtin_ia32_fixupimmps128_mask: + case X86::BI__builtin_ia32_fixupimmps128_maskz: + case X86::BI__builtin_ia32_fixupimmps256_mask: + case X86::BI__builtin_ia32_fixupimmps256_maskz: + case X86::BI__builtin_ia32_pternlogd512_mask: + case X86::BI__builtin_ia32_pternlogd512_maskz: + case X86::BI__builtin_ia32_pternlogq512_mask: + case X86::BI__builtin_ia32_pternlogq512_maskz: + case X86::BI__builtin_ia32_pternlogd128_mask: + case X86::BI__builtin_ia32_pternlogd128_maskz: + case X86::BI__builtin_ia32_pternlogd256_mask: + case X86::BI__builtin_ia32_pternlogd256_maskz: + case X86::BI__builtin_ia32_pternlogq128_mask: + case X86::BI__builtin_ia32_pternlogq128_maskz: + case X86::BI__builtin_ia32_pternlogq256_mask: + case X86::BI__builtin_ia32_pternlogq256_maskz: + case X86::BI__builtin_ia32_vsm3rnds2: + i = 3; + l = 0; + u = 255; + break; + case X86::BI__builtin_ia32_reducesd_mask: + case X86::BI__builtin_ia32_reducess_mask: + case X86::BI__builtin_ia32_rndscalesd_round_mask: + case X86::BI__builtin_ia32_rndscaless_round_mask: + case X86::BI__builtin_ia32_rndscalesh_round_mask: + case X86::BI__builtin_ia32_reducesh_mask: + i = 4; + l = 0; + u = 255; + break; + case X86::BI__builtin_ia32_cmpccxadd32: + case X86::BI__builtin_ia32_cmpccxadd64: + i = 3; + l = 0; + u = 15; + break; + } + + // Note that we don't force a hard error on the range check here, allowing + // template-generated or macro-generated dead code to potentially have out-of- + // range values. These need to code generate, but don't need to necessarily + // make any sense. We use a warning that defaults to an error. + return SemaRef.BuiltinConstantArgRange(TheCall, i, l, u, + /*RangeIsError*/ false); +} + +} // namespace clang diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 06ed0843ef504..dee335b526991 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -42,6 +42,7 @@ #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/SemaOpenMP.h" +#include "clang/Sema/SemaPseudoObject.h" #include "clang/Sema/SemaSYCL.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/ErrorHandling.h" @@ -7336,7 +7337,7 @@ QualType TreeTransform::TransformCountAttributedType( if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() || OldCount != NewCount) { // Currently, CountAttributedType can only wrap incomplete array types. - Result = SemaRef.BuildCountAttributedArrayType(InnerTy, NewCount); + Result = SemaRef.BuildCountAttributedArrayOrPointerType(InnerTy, NewCount); } TLB.push(Result); @@ -11125,7 +11126,8 @@ class OpenACCClauseTransform final if (!Res.isUsable()) continue; - Res = Self.getSema().OpenACC().ActOnVar(Res.get()); + Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(), + Res.get()); if (Res.isUsable()) InstantiatedVarList.push_back(Res.get()); @@ -11485,6 +11487,24 @@ void OpenACCClauseTransform::VisitDeviceTypeClause( ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(), C.getArchitectures(), ParsedClause.getEndLoc()); } + +template +void OpenACCClauseTransform::VisitReductionClause( + const OpenACCReductionClause &C) { + SmallVector TransformedVars = VisitVarList(C.getVarList()); + SmallVector ValidVars; + + for (Expr *Var : TransformedVars) { + ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(Var); + if (Res.isUsable()) + ValidVars.push_back(Res.get()); + } + + NewClause = OpenACCReductionClause::Create( + Self.getSema().getASTContext(), ParsedClause.getBeginLoc(), + ParsedClause.getLParenLoc(), C.getReductionOp(), ValidVars, + ParsedClause.getEndLoc()); +} } // namespace template OpenACCClause *TreeTransform::TransformOpenACCClause( @@ -11882,7 +11902,7 @@ TreeTransform::TransformPseudoObjectExpr(PseudoObjectExpr *E) { // better solution (rebuilding the semantic expressions and // rebinding OVEs as necessary) doesn't work; we'd need // TreeTransform to not strip away implicit conversions. - Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E); + Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E); ExprResult result = getDerived().TransformExpr(newSyntacticForm); if (result.isInvalid()) return ExprError(); @@ -11890,7 +11910,7 @@ TreeTransform::TransformPseudoObjectExpr(PseudoObjectExpr *E) { // expression must have been an lvalue-to-rvalue conversion which we // should reapply. if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject)) - result = SemaRef.checkPseudoObjectRValue(result.get()); + result = SemaRef.PseudoObject().checkRValue(result.get()); return result; } @@ -14094,6 +14114,13 @@ TreeTransform::TransformCXXTemporaryObjectExpr( if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, &ArgumentChanged)) return ExprError(); + + if (E->isListInitialization() && !E->isStdInitListInitialization()) { + ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc()); + if (Res.isInvalid()) + return ExprError(); + Args = {Res.get()}; + } } if (!getDerived().AlwaysRebuild() && @@ -14105,12 +14132,9 @@ TreeTransform::TransformCXXTemporaryObjectExpr( return SemaRef.MaybeBindToTemporary(E); } - // FIXME: We should just pass E->isListInitialization(), but we're not - // prepared to handle list-initialization without a child InitListExpr. SourceLocation LParenLoc = T->getTypeLoc().getEndLoc(); return getDerived().RebuildCXXTemporaryObjectExpr( - T, LParenLoc, Args, E->getEndLoc(), - /*ListInitialization=*/LParenLoc.isInvalid()); + T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization()); } template @@ -16186,8 +16210,8 @@ ExprResult TreeTransform::RebuildCXXOperatorCallExpr( if (First->getObjectKind() == OK_ObjCProperty) { BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); if (BinaryOperator::isAssignmentOp(Opc)) - return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc, - First, Second); + return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc, + Opc, First, Second); ExprResult Result = SemaRef.CheckPlaceholderExpr(First); if (Result.isInvalid()) return ExprError(); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index f50f9569c0a5e..4a6e1d23161be 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1264,7 +1264,7 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, if (!Lex.first) { Lex = std::make_pair( &M, llvm::ArrayRef( - reinterpret_cast(Blob.data()), + reinterpret_cast(Blob.data()), Blob.size() / sizeof(DeclID))); } DC->setHasExternalLexicalStorage(true); @@ -3401,7 +3401,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case TU_UPDATE_LEXICAL: { DeclContext *TU = ContextObj->getTranslationUnitDecl(); LexicalContents Contents( - reinterpret_cast(Blob.data()), + reinterpret_cast(Blob.data()), static_cast(Blob.size() / sizeof(DeclID))); TULexicalDecls.push_back(std::make_pair(&F, Contents)); TU->setHasExternalLexicalStorage(true); @@ -4059,7 +4059,7 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { RemapBuilder DeclRemap(F.DeclRemap); RemapBuilder TypeRemap(F.TypeRemap); - auto &ImportedModuleVector = F.DependentModules; + auto &ImportedModuleVector = F.TransitiveImports; assert(ImportedModuleVector.empty()); while (Data < DataEnd) { @@ -11921,6 +11921,13 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { return OpenACCDeviceTypeClause::Create(getContext(), ClauseKind, BeginLoc, LParenLoc, Archs, EndLoc); } + case OpenACCClauseKind::Reduction: { + SourceLocation LParenLoc = readSourceLocation(); + OpenACCReductionOperator Op = readEnum(); + llvm::SmallVector VarList = readOpenACCVarList(); + return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op, + VarList, EndLoc); + } case OpenACCClauseKind::Finalize: case OpenACCClauseKind::IfPresent: @@ -11937,7 +11944,6 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { case OpenACCClauseKind::DeviceResident: case OpenACCClauseKind::Host: case OpenACCClauseKind::Link: - case OpenACCClauseKind::Reduction: case OpenACCClauseKind::Collapse: case OpenACCClauseKind::Bind: case OpenACCClauseKind::DeviceNum: diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index a6254b70560c3..61cc99d4df687 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2695,7 +2695,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } if (Record.readInt()) - D->setDefaultArgument(readTypeSourceInfo()); + D->setDefaultArgument(Reader.getContext(), + Record.readTemplateArgumentLoc()); } void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { @@ -2716,7 +2717,8 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // Rest of NonTypeTemplateParmDecl. D->ParameterPack = Record.readInt(); if (Record.readInt()) - D->setDefaultArgument(Record.readExpr()); + D->setDefaultArgument(Reader.getContext(), + Record.readTemplateArgumentLoc()); } } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 1d6d96932ba2c..00b0e48083217 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -7959,6 +7959,13 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { } return; } + case OpenACCClauseKind::Reduction: { + const auto *RC = cast(C); + writeSourceLocation(RC->getLParenLoc()); + writeEnum(RC->getReductionOp()); + writeOpenACCVarList(RC); + return; + } case OpenACCClauseKind::Finalize: case OpenACCClauseKind::IfPresent: @@ -7975,7 +7982,6 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { case OpenACCClauseKind::DeviceResident: case OpenACCClauseKind::Host: case OpenACCClauseKind::Link: - case OpenACCClauseKind::Reduction: case OpenACCClauseKind::Collapse: case OpenACCClauseKind::Bind: case OpenACCClauseKind::DeviceNum: diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index c2f1d1b44241c..bbd16dbdb8fff 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1899,7 +1899,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { !D->defaultArgumentWasInherited(); Record.push_back(OwnsDefaultArg); if (OwnsDefaultArg) - Record.AddTypeSourceInfo(D->getDefaultArgumentInfo()); + Record.AddTemplateArgumentLoc(D->getDefaultArgument()); if (!TC && !OwnsDefaultArg && D->getDeclContext() == D->getLexicalDeclContext() && @@ -1941,7 +1941,7 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { !D->defaultArgumentWasInherited(); Record.push_back(OwnsDefaultArg); if (OwnsDefaultArg) - Record.AddStmt(D->getDefaultArgument()); + Record.AddTemplateArgumentLoc(D->getDefaultArgument()); Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM; } } diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 4443ffd092938..cd5a3bdd02e4a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -96,13 +96,14 @@ add_clang_library(clangStaticAnalyzerCheckers PointerSortingChecker.cpp PointerSubChecker.cpp PthreadLockChecker.cpp - cert/PutenvWithAutoChecker.cpp + PutenvStackArrayChecker.cpp RetainCountChecker/RetainCountChecker.cpp RetainCountChecker/RetainCountDiagnostics.cpp ReturnPointerRangeChecker.cpp ReturnUndefChecker.cpp ReturnValueChecker.cpp RunLoopAutoreleaseLeakChecker.cpp + SetgidSetuidOrderChecker.cpp SimpleStreamChecker.cpp SmartPtrChecker.cpp SmartPtrModeling.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp similarity index 62% rename from clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp rename to clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp index a82f7caf16b29..bf81d57bf82fd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp @@ -1,4 +1,4 @@ -//== PutenvWithAutoChecker.cpp --------------------------------- -*- C++ -*--=// +//== PutenvStackArrayChecker.cpp ------------------------------- -*- C++ -*--=// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// // -// This file defines PutenvWithAutoChecker which finds calls of ``putenv`` -// function with automatic variable as the argument. +// This file defines PutenvStackArrayChecker which finds calls of ``putenv`` +// function with automatic array variable as the argument. // https://wiki.sei.cmu.edu/confluence/x/6NYxBQ // //===----------------------------------------------------------------------===// -#include "../AllocationState.h" +#include "AllocationState.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -26,9 +26,9 @@ using namespace clang; using namespace ento; namespace { -class PutenvWithAutoChecker : public Checker { +class PutenvStackArrayChecker : public Checker { private: - BugType BT{this, "'putenv' function should not be called with auto variables", + BugType BT{this, "'putenv' called with stack-allocated string", categories::SecurityError}; const CallDescription Putenv{CDM::CLibrary, {"putenv"}, 1}; @@ -37,20 +37,25 @@ class PutenvWithAutoChecker : public Checker { }; } // namespace -void PutenvWithAutoChecker::checkPostCall(const CallEvent &Call, - CheckerContext &C) const { +void PutenvStackArrayChecker::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { if (!Putenv.matches(Call)) return; SVal ArgV = Call.getArgSVal(0); const Expr *ArgExpr = Call.getArgExpr(0); - const MemSpaceRegion *MSR = ArgV.getAsRegion()->getMemorySpace(); - if (!isa(MSR)) + const auto *SSR = + dyn_cast(ArgV.getAsRegion()->getMemorySpace()); + if (!SSR) + return; + const auto *StackFrameFuncD = + dyn_cast_or_null(SSR->getStackFrame()->getDecl()); + if (StackFrameFuncD && StackFrameFuncD->isMain()) return; StringRef ErrorMsg = "The 'putenv' function should not be called with " - "arguments that have automatic storage"; + "arrays that have automatic storage"; ExplodedNode *N = C.generateErrorNode(); auto Report = std::make_unique(BT, ErrorMsg, N); @@ -60,8 +65,10 @@ void PutenvWithAutoChecker::checkPostCall(const CallEvent &Call, C.emitReport(std::move(Report)); } -void ento::registerPutenvWithAuto(CheckerManager &Mgr) { - Mgr.registerChecker(); +void ento::registerPutenvStackArray(CheckerManager &Mgr) { + Mgr.registerChecker(); } -bool ento::shouldRegisterPutenvWithAuto(const CheckerManager &) { return true; } +bool ento::shouldRegisterPutenvStackArray(const CheckerManager &) { + return true; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/SetgidSetuidOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SetgidSetuidOrderChecker.cpp new file mode 100644 index 0000000000000..dbe3fd33a6b43 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/SetgidSetuidOrderChecker.cpp @@ -0,0 +1,196 @@ +//===-- SetgidSetuidOrderChecker.cpp - check privilege revocation calls ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a checker to detect possible reversed order of privilege +// revocations when 'setgid' and 'setuid' is used. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" + +using namespace clang; +using namespace ento; + +namespace { + +enum SetPrivilegeFunctionKind { Irrelevant, Setuid, Setgid }; + +class SetgidSetuidOrderChecker : public Checker { + const BugType BT{this, "Possible wrong order of privilege revocation"}; + + const CallDescription SetuidDesc{CDM::CLibrary, {"setuid"}, 1}; + const CallDescription SetgidDesc{CDM::CLibrary, {"setgid"}, 1}; + + const CallDescription GetuidDesc{CDM::CLibrary, {"getuid"}, 0}; + const CallDescription GetgidDesc{CDM::CLibrary, {"getgid"}, 0}; + + const CallDescriptionSet OtherSetPrivilegeDesc{ + {CDM::CLibrary, {"seteuid"}, 1}, {CDM::CLibrary, {"setegid"}, 1}, + {CDM::CLibrary, {"setreuid"}, 2}, {CDM::CLibrary, {"setregid"}, 2}, + {CDM::CLibrary, {"setresuid"}, 3}, {CDM::CLibrary, {"setresgid"}, 3}}; + +public: + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; + ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond, + bool Assumption) const; + +private: + void processSetuid(ProgramStateRef State, const CallEvent &Call, + CheckerContext &C) const; + void processSetgid(ProgramStateRef State, const CallEvent &Call, + CheckerContext &C) const; + void processOther(ProgramStateRef State, const CallEvent &Call, + CheckerContext &C) const; + /// Check if a function like \c getuid or \c getgid is called directly from + /// the first argument of function called from \a Call. + bool isFunctionCalledInArg(const CallDescription &Desc, + const CallEvent &Call) const; + void emitReport(ProgramStateRef State, CheckerContext &C) const; +}; + +} // end anonymous namespace + +/// Store if there was a call to 'setuid(getuid())' or 'setgid(getgid())' not +/// followed by other different privilege-change functions. +/// If the value \c Setuid is stored and a 'setgid(getgid())' call is found we +/// have found the bug to be reported. Value \c Setgid is used too to prevent +/// warnings at a setgid-setuid-setgid sequence. +REGISTER_TRAIT_WITH_PROGRAMSTATE(LastSetPrivilegeCall, SetPrivilegeFunctionKind) +/// Store the symbol value of the last 'setuid(getuid())' call. This is used to +/// detect if the result is compared to -1 and avoid warnings on that branch +/// (which is the failure branch of the call), and for identification of note +/// tags. +REGISTER_TRAIT_WITH_PROGRAMSTATE(LastSetuidCallSVal, SymbolRef) + +void SetgidSetuidOrderChecker::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + if (SetuidDesc.matches(Call)) { + processSetuid(State, Call, C); + } else if (SetgidDesc.matches(Call)) { + processSetgid(State, Call, C); + } else if (OtherSetPrivilegeDesc.contains(Call)) { + processOther(State, Call, C); + } +} + +ProgramStateRef SetgidSetuidOrderChecker::evalAssume(ProgramStateRef State, + SVal Cond, + bool Assumption) const { + SValBuilder &SVB = State->getStateManager().getSValBuilder(); + SymbolRef LastSetuidSym = State->get(); + if (!LastSetuidSym) + return State; + + // Check if the most recent call to 'setuid(getuid())' is assumed to be != 0. + // It should be only -1 at failure, but we want to accept a "!= 0" check too. + // (But now an invalid failure check like "!= 1" will be recognized as correct + // too. The "invalid failure check" is a different bug that is not the scope + // of this checker.) + auto FailComparison = + SVB.evalBinOpNN(State, BO_NE, nonloc::SymbolVal(LastSetuidSym), + SVB.makeIntVal(0, /*isUnsigned=*/false), + SVB.getConditionType()) + .getAs(); + if (!FailComparison) + return State; + if (auto IsFailBranch = State->assume(*FailComparison); + IsFailBranch.first && !IsFailBranch.second) { + // This is the 'setuid(getuid())' != 0 case. + // On this branch we do not want to emit warning. + State = State->set(Irrelevant); + State = State->set(SymbolRef{}); + } + return State; +} + +void SetgidSetuidOrderChecker::processSetuid(ProgramStateRef State, + const CallEvent &Call, + CheckerContext &C) const { + bool IsSetuidWithGetuid = isFunctionCalledInArg(GetuidDesc, Call); + if (State->get() != Setgid && IsSetuidWithGetuid) { + SymbolRef RetSym = Call.getReturnValue().getAsSymbol(); + State = State->set(Setuid); + State = State->set(RetSym); + const NoteTag *Note = C.getNoteTag([this, + RetSym](PathSensitiveBugReport &BR) { + if (!BR.isInteresting(RetSym) || &BR.getBugType() != &this->BT) + return ""; + return "Call to 'setuid' found here that removes superuser privileges"; + }); + C.addTransition(State, Note); + return; + } + State = State->set(Irrelevant); + State = State->set(SymbolRef{}); + C.addTransition(State); +} + +void SetgidSetuidOrderChecker::processSetgid(ProgramStateRef State, + const CallEvent &Call, + CheckerContext &C) const { + bool IsSetgidWithGetgid = isFunctionCalledInArg(GetgidDesc, Call); + if (State->get() == Setuid) { + if (IsSetgidWithGetgid) { + State = State->set(Irrelevant); + emitReport(State, C); + return; + } + State = State->set(Irrelevant); + } else { + State = State->set(IsSetgidWithGetgid ? Setgid + : Irrelevant); + } + State = State->set(SymbolRef{}); + C.addTransition(State); +} + +void SetgidSetuidOrderChecker::processOther(ProgramStateRef State, + const CallEvent &Call, + CheckerContext &C) const { + State = State->set(SymbolRef{}); + State = State->set(Irrelevant); + C.addTransition(State); +} + +bool SetgidSetuidOrderChecker::isFunctionCalledInArg( + const CallDescription &Desc, const CallEvent &Call) const { + if (const auto *CallInArg0 = + dyn_cast(Call.getArgExpr(0)->IgnoreParenImpCasts())) + return Desc.matchesAsWritten(*CallInArg0); + return false; +} + +void SetgidSetuidOrderChecker::emitReport(ProgramStateRef State, + CheckerContext &C) const { + if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) { + llvm::StringLiteral Msg = + "A 'setgid(getgid())' call following a 'setuid(getuid())' " + "call is likely to fail; probably the order of these " + "statements is wrong"; + auto Report = std::make_unique(BT, Msg, N); + Report->markInteresting(State->get()); + C.emitReport(std::move(Report)); + } +} + +void ento::registerSetgidSetuidOrderChecker(CheckerManager &mgr) { + mgr.registerChecker(); +} + +bool ento::shouldRegisterSetgidSetuidOrderChecker(const CheckerManager &mgr) { + return true; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index 5c797d5233089..49bbff1942167 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -271,6 +271,43 @@ class TrivialFunctionAnalysisVisitor TrivialFunctionAnalysisVisitor(CacheTy &Cache) : Cache(Cache) {} + bool IsFunctionTrivial(const Decl *D) { + auto CacheIt = Cache.find(D); + if (CacheIt != Cache.end()) + return CacheIt->second; + + // Treat a recursive function call to be trivial until proven otherwise. + auto [RecursiveIt, IsNew] = RecursiveFn.insert(std::make_pair(D, true)); + if (!IsNew) + return RecursiveIt->second; + + bool Result = [&]() { + if (auto *CtorDecl = dyn_cast(D)) { + for (auto *CtorInit : CtorDecl->inits()) { + if (!Visit(CtorInit->getInit())) + return false; + } + } + const Stmt *Body = D->getBody(); + if (!Body) + return false; + return Visit(Body); + }(); + + if (!Result) { + // D and its mutually recursive callers are all non-trivial. + for (auto &It : RecursiveFn) + It.second = false; + } + RecursiveIt = RecursiveFn.find(D); + assert(RecursiveIt != RecursiveFn.end()); + Result = RecursiveIt->second; + RecursiveFn.erase(RecursiveIt); + Cache[D] = Result; + + return Result; + } + bool VisitStmt(const Stmt *S) { // All statements are non-trivial unless overriden later. // Don't even recurse into children by default. @@ -368,7 +405,7 @@ class TrivialFunctionAnalysisVisitor Name == "bitwise_cast" || Name.find("__builtin") == 0) return true; - return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache); + return IsFunctionTrivial(Callee); } bool @@ -403,7 +440,7 @@ class TrivialFunctionAnalysisVisitor return true; // Recursively descend into the callee to confirm that it's trivial as well. - return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache); + return IsFunctionTrivial(Callee); } bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) { @@ -413,7 +450,7 @@ class TrivialFunctionAnalysisVisitor if (!Callee) return false; // Recursively descend into the callee to confirm that it's trivial as well. - return TrivialFunctionAnalysis::isTrivialImpl(Callee, Cache); + return IsFunctionTrivial(Callee); } bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { @@ -439,7 +476,7 @@ class TrivialFunctionAnalysisVisitor } // Recursively descend into the callee to confirm that it's trivial. - return TrivialFunctionAnalysis::isTrivialImpl(CE->getConstructor(), Cache); + return IsFunctionTrivial(CE->getConstructor()); } bool VisitCXXNewExpr(const CXXNewExpr *NE) { return VisitChildren(NE); } @@ -513,36 +550,13 @@ class TrivialFunctionAnalysisVisitor private: CacheTy &Cache; + CacheTy RecursiveFn; }; bool TrivialFunctionAnalysis::isTrivialImpl( const Decl *D, TrivialFunctionAnalysis::CacheTy &Cache) { - // If the function isn't in the cache, conservatively assume that - // it's not trivial until analysis completes. This makes every recursive - // function non-trivial. This also guarantees that each function - // will be scanned at most once. - auto [It, IsNew] = Cache.insert(std::make_pair(D, false)); - if (!IsNew) - return It->second; - TrivialFunctionAnalysisVisitor V(Cache); - - if (auto *CtorDecl = dyn_cast(D)) { - for (auto *CtorInit : CtorDecl->inits()) { - if (!V.Visit(CtorInit->getInit())) - return false; - } - } - - const Stmt *Body = D->getBody(); - if (!Body) - return false; - - bool Result = V.Visit(Body); - if (Result) - Cache[D] = true; - - return Result; + return V.IsFunctionTrivial(D); } bool TrivialFunctionAnalysis::isTrivialImpl( diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp index 7f4c3a7b787e8..9df108e28ecdb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -11,16 +11,116 @@ #include "PtrTypesSemantics.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SetVector.h" #include using namespace clang; using namespace ento; namespace { + +class DerefFuncDeleteExprVisitor + : public ConstStmtVisitor { + // Returns true if any of child statements return true. + bool VisitChildren(const Stmt *S) { + for (const Stmt *Child : S->children()) { + if (Child && Visit(Child)) + return true; + } + return false; + } + + bool VisitBody(const Stmt *Body) { + if (!Body) + return false; + + auto [It, IsNew] = VisitedBody.insert(Body); + if (!IsNew) // This body is recursive + return false; + + return Visit(Body); + } + +public: + DerefFuncDeleteExprVisitor(const TemplateArgumentList &ArgList, + const CXXRecordDecl *ClassDecl) + : ArgList(&ArgList), ClassDecl(ClassDecl) {} + + DerefFuncDeleteExprVisitor(const CXXRecordDecl *ClassDecl) + : ClassDecl(ClassDecl) {} + + std::optional HasSpecializedDelete(CXXMethodDecl *Decl) { + if (auto *Body = Decl->getBody()) + return VisitBody(Body); + if (Decl->getTemplateInstantiationPattern()) + return std::nullopt; // Indeterminate. There was no concrete instance. + return false; + } + + bool VisitCallExpr(const CallExpr *CE) { + const Decl *D = CE->getCalleeDecl(); + if (D && D->hasBody()) + return VisitBody(D->getBody()); + return false; + } + + bool VisitCXXDeleteExpr(const CXXDeleteExpr *E) { + auto *Arg = E->getArgument(); + while (Arg) { + if (auto *Paren = dyn_cast(Arg)) + Arg = Paren->getSubExpr(); + else if (auto *Cast = dyn_cast(Arg)) { + Arg = Cast->getSubExpr(); + auto CastType = Cast->getType(); + if (auto *PtrType = dyn_cast(CastType)) { + auto PointeeType = PtrType->getPointeeType(); + while (auto *ET = dyn_cast(PointeeType)) { + if (ET->isSugared()) + PointeeType = ET->desugar(); + } + if (auto *ParmType = dyn_cast(PointeeType)) { + if (ArgList) { + auto ParmIndex = ParmType->getIndex(); + auto Type = ArgList->get(ParmIndex).getAsType(); + if (Type->getAsCXXRecordDecl() == ClassDecl) + return true; + } + } else if (auto *RD = dyn_cast(PointeeType)) { + if (RD->getDecl() == ClassDecl) + return true; + } else if (auto *ST = + dyn_cast(PointeeType)) { + auto Type = ST->getReplacementType(); + if (auto *RD = dyn_cast(Type)) { + if (RD->getDecl() == ClassDecl) + return true; + } + } + } + } else + break; + } + return false; + } + + bool VisitStmt(const Stmt *S) { return VisitChildren(S); } + + // Return false since the contents of lambda isn't necessarily executed. + // If it is executed, VisitCallExpr above will visit its body. + bool VisitLambdaExpr(const LambdaExpr *) { return false; } + +private: + const TemplateArgumentList *ArgList{nullptr}; + const CXXRecordDecl *ClassDecl; + llvm::DenseSet VisitedBody; +}; + class RefCntblBaseVirtualDtorChecker : public Checker> { private: @@ -51,63 +151,93 @@ class RefCntblBaseVirtualDtorChecker bool shouldVisitImplicitCode() const { return false; } bool VisitCXXRecordDecl(const CXXRecordDecl *RD) { - Checker->visitCXXRecordDecl(RD); + if (!RD->hasDefinition()) + return true; + + Decls.insert(RD); + + for (auto &Base : RD->bases()) { + const auto AccSpec = Base.getAccessSpecifier(); + if (AccSpec == AS_protected || AccSpec == AS_private || + (AccSpec == AS_none && RD->isClass())) + continue; + + QualType T = Base.getType(); + if (T.isNull()) + continue; + + const CXXRecordDecl *C = T->getAsCXXRecordDecl(); + if (!C) + continue; + + if (auto *CTSD = dyn_cast(C)) { + for (auto &Arg : CTSD->getTemplateArgs().asArray()) { + if (Arg.getKind() != TemplateArgument::Type) + continue; + auto TemplT = Arg.getAsType(); + if (TemplT.isNull()) + continue; + + bool IsCRTP = TemplT->getAsCXXRecordDecl() == RD; + if (!IsCRTP) + continue; + CRTPs.insert(C); + } + } + } + return true; } + + llvm::SetVector Decls; + llvm::DenseSet CRTPs; }; LocalVisitor visitor(this); visitor.TraverseDecl(const_cast(TUD)); + for (auto *RD : visitor.Decls) { + if (visitor.CRTPs.contains(RD)) + continue; + visitCXXRecordDecl(RD); + } } void visitCXXRecordDecl(const CXXRecordDecl *RD) const { if (shouldSkipDecl(RD)) return; - CXXBasePaths Paths; - Paths.setOrigin(RD); + for (auto &Base : RD->bases()) { + const auto AccSpec = Base.getAccessSpecifier(); + if (AccSpec == AS_protected || AccSpec == AS_private || + (AccSpec == AS_none && RD->isClass())) + continue; - const CXXBaseSpecifier *ProblematicBaseSpecifier = nullptr; - const CXXRecordDecl *ProblematicBaseClass = nullptr; + auto hasRefInBase = clang::hasPublicMethodInBase(&Base, "ref"); + auto hasDerefInBase = clang::hasPublicMethodInBase(&Base, "deref"); - const auto IsPublicBaseRefCntblWOVirtualDtor = - [RD, &ProblematicBaseSpecifier, - &ProblematicBaseClass](const CXXBaseSpecifier *Base, CXXBasePath &) { - const auto AccSpec = Base->getAccessSpecifier(); - if (AccSpec == AS_protected || AccSpec == AS_private || - (AccSpec == AS_none && RD->isClass())) - return false; + bool hasRef = hasRefInBase && *hasRefInBase != nullptr; + bool hasDeref = hasDerefInBase && *hasDerefInBase != nullptr; - auto hasRefInBase = clang::hasPublicMethodInBase(Base, "ref"); - auto hasDerefInBase = clang::hasPublicMethodInBase(Base, "deref"); + QualType T = Base.getType(); + if (T.isNull()) + continue; - bool hasRef = hasRefInBase && *hasRefInBase != nullptr; - bool hasDeref = hasDerefInBase && *hasDerefInBase != nullptr; + const CXXRecordDecl *C = T->getAsCXXRecordDecl(); + if (!C) + continue; - QualType T = Base->getType(); - if (T.isNull()) - return false; - - const CXXRecordDecl *C = T->getAsCXXRecordDecl(); - if (!C) - return false; - if (isRefCountedClass(C)) - return false; - - bool AnyInconclusiveBase = false; - const auto hasPublicRefInBase = - [&AnyInconclusiveBase](const CXXBaseSpecifier *Base, - CXXBasePath &) { - auto hasRefInBase = clang::hasPublicMethodInBase(Base, "ref"); - if (!hasRefInBase) { - AnyInconclusiveBase = true; - return false; - } - return (*hasRefInBase) != nullptr; - }; - const auto hasPublicDerefInBase = [&AnyInconclusiveBase]( - const CXXBaseSpecifier *Base, - CXXBasePath &) { + bool AnyInconclusiveBase = false; + const auto hasPublicRefInBase = + [&AnyInconclusiveBase](const CXXBaseSpecifier *Base, CXXBasePath &) { + auto hasRefInBase = clang::hasPublicMethodInBase(Base, "ref"); + if (!hasRefInBase) { + AnyInconclusiveBase = true; + return false; + } + return (*hasRefInBase) != nullptr; + }; + const auto hasPublicDerefInBase = + [&AnyInconclusiveBase](const CXXBaseSpecifier *Base, CXXBasePath &) { auto hasDerefInBase = clang::hasPublicMethodInBase(Base, "deref"); if (!hasDerefInBase) { AnyInconclusiveBase = true; @@ -115,28 +245,42 @@ class RefCntblBaseVirtualDtorChecker } return (*hasDerefInBase) != nullptr; }; - CXXBasePaths Paths; - Paths.setOrigin(C); - hasRef = hasRef || C->lookupInBases(hasPublicRefInBase, Paths, + CXXBasePaths Paths; + Paths.setOrigin(C); + hasRef = hasRef || C->lookupInBases(hasPublicRefInBase, Paths, + /*LookupInDependent =*/true); + hasDeref = hasDeref || C->lookupInBases(hasPublicDerefInBase, Paths, /*LookupInDependent =*/true); - hasDeref = hasDeref || C->lookupInBases(hasPublicDerefInBase, Paths, - /*LookupInDependent =*/true); - if (AnyInconclusiveBase || !hasRef || !hasDeref) - return false; - - const auto *Dtor = C->getDestructor(); - if (!Dtor || !Dtor->isVirtual()) { - ProblematicBaseSpecifier = Base; - ProblematicBaseClass = C; - return true; - } - - return false; - }; - - if (RD->lookupInBases(IsPublicBaseRefCntblWOVirtualDtor, Paths, - /*LookupInDependent =*/true)) { - reportBug(RD, ProblematicBaseSpecifier, ProblematicBaseClass); + if (AnyInconclusiveBase || !hasRef || !hasDeref) + continue; + + auto HasSpecializedDelete = isClassWithSpecializedDelete(C, RD); + if (!HasSpecializedDelete || *HasSpecializedDelete) + continue; + if (C->lookupInBases( + [&](const CXXBaseSpecifier *Base, CXXBasePath &) { + auto *T = Base->getType().getTypePtrOrNull(); + if (!T) + return false; + auto *R = T->getAsCXXRecordDecl(); + if (!R) + return false; + auto Result = isClassWithSpecializedDelete(R, RD); + if (!Result) + AnyInconclusiveBase = true; + return Result && *Result; + }, + Paths, /*LookupInDependent =*/true)) + continue; + if (AnyInconclusiveBase) + continue; + + const auto *Dtor = C->getDestructor(); + if (!Dtor || !Dtor->isVirtual()) { + auto *ProblematicBaseSpecifier = &Base; + auto *ProblematicBaseClass = C; + reportBug(RD, ProblematicBaseSpecifier, ProblematicBaseClass); + } } } @@ -182,6 +326,32 @@ class RefCntblBaseVirtualDtorChecker ClsName == "ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr"); } + static std::optional + isClassWithSpecializedDelete(const CXXRecordDecl *C, + const CXXRecordDecl *DerivedClass) { + if (auto *ClsTmplSpDecl = dyn_cast(C)) { + for (auto *MethodDecl : C->methods()) { + if (safeGetName(MethodDecl) == "deref") { + DerefFuncDeleteExprVisitor Visitor(ClsTmplSpDecl->getTemplateArgs(), + DerivedClass); + auto Result = Visitor.HasSpecializedDelete(MethodDecl); + if (!Result || *Result) + return Result; + } + } + return false; + } + for (auto *MethodDecl : C->methods()) { + if (safeGetName(MethodDecl) == "deref") { + DerefFuncDeleteExprVisitor Visitor(DerivedClass); + auto Result = Visitor.HasSpecializedDelete(MethodDecl); + if (!Result || *Result) + return Result; + } + } + return false; + } + void reportBug(const CXXRecordDecl *DerivedClass, const CXXBaseSpecifier *BaseSpec, const CXXRecordDecl *ProblematicBaseClass) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp index 0d9710a5e2d83..274da0baf2ce5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLocalVarsChecker.cpp @@ -135,7 +135,19 @@ class UncountedLocalVarsChecker bool shouldVisitImplicitCode() const { return false; } bool VisitVarDecl(VarDecl *V) { - Checker->visitVarDecl(V); + auto *Init = V->getInit(); + if (Init && V->isLocalVarDecl()) + Checker->visitVarDecl(V, Init); + return true; + } + + bool VisitBinaryOperator(const BinaryOperator *BO) { + if (BO->isAssignmentOp()) { + if (auto *VarRef = dyn_cast(BO->getLHS())) { + if (auto *V = dyn_cast(VarRef->getDecl())) + Checker->visitVarDecl(V, BO->getRHS()); + } + } return true; } @@ -174,7 +186,7 @@ class UncountedLocalVarsChecker visitor.TraverseDecl(const_cast(TUD)); } - void visitVarDecl(const VarDecl *V) const { + void visitVarDecl(const VarDecl *V, const Expr *Value) const { if (shouldSkipVarDecl(V)) return; @@ -184,12 +196,8 @@ class UncountedLocalVarsChecker std::optional IsUncountedPtr = isUncountedPtr(ArgType); if (IsUncountedPtr && *IsUncountedPtr) { - const Expr *const InitExpr = V->getInit(); - if (!InitExpr) - return; // FIXME: later on we might warn on uninitialized vars too - if (tryToFindPtrOrigin( - InitExpr, /*StopAtFirstRefCountedObj=*/false, + Value, /*StopAtFirstRefCountedObj=*/false, [&](const clang::Expr *InitArgOrigin, bool IsSafe) { if (!InitArgOrigin) return true; @@ -232,34 +240,46 @@ class UncountedLocalVarsChecker })) return; - reportBug(V); + reportBug(V, Value); } } bool shouldSkipVarDecl(const VarDecl *V) const { assert(V); - if (!V->isLocalVarDecl()) - return true; - - if (BR->getSourceManager().isInSystemHeader(V->getLocation())) - return true; - - return false; + return BR->getSourceManager().isInSystemHeader(V->getLocation()); } - void reportBug(const VarDecl *V) const { + void reportBug(const VarDecl *V, const Expr *Value) const { assert(V); SmallString<100> Buf; llvm::raw_svector_ostream Os(Buf); - Os << "Local variable "; - printQuotedQualifiedName(Os, V); - Os << " is uncounted and unsafe."; - - PathDiagnosticLocation BSLoc(V->getLocation(), BR->getSourceManager()); - auto Report = std::make_unique(Bug, Os.str(), BSLoc); - Report->addRange(V->getSourceRange()); - BR->emitReport(std::move(Report)); + if (dyn_cast(V)) { + Os << "Assignment to an uncounted parameter "; + printQuotedQualifiedName(Os, V); + Os << " is unsafe."; + + PathDiagnosticLocation BSLoc(Value->getExprLoc(), BR->getSourceManager()); + auto Report = std::make_unique(Bug, Os.str(), BSLoc); + Report->addRange(Value->getSourceRange()); + BR->emitReport(std::move(Report)); + } else { + if (V->hasLocalStorage()) + Os << "Local variable "; + else if (V->isStaticLocal()) + Os << "Static local variable "; + else if (V->hasGlobalStorage()) + Os << "Global variable "; + else + Os << "Variable "; + printQuotedQualifiedName(Os, V); + Os << " is uncounted and unsafe."; + + PathDiagnosticLocation BSLoc(V->getLocation(), BR->getSourceManager()); + auto Report = std::make_unique(Bug, Os.str(), BSLoc); + Report->addRange(V->getSourceRange()); + BR->emitReport(std::move(Report)); + } } }; } // namespace diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 0b1edf3e5c96b..793f3a63ea29e 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1970,33 +1970,45 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet Tmp; StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); - const Expr *ArgE; - if (const auto *DefE = dyn_cast(S)) + bool HasRewrittenInit = false; + const Expr *ArgE = nullptr; + if (const auto *DefE = dyn_cast(S)) { ArgE = DefE->getExpr(); - else if (const auto *DefE = dyn_cast(S)) + HasRewrittenInit = DefE->hasRewrittenInit(); + } else if (const auto *DefE = dyn_cast(S)) { ArgE = DefE->getExpr(); - else + HasRewrittenInit = DefE->hasRewrittenInit(); + } else llvm_unreachable("unknown constant wrapper kind"); - bool IsTemporary = false; - if (const auto *MTE = dyn_cast(ArgE)) { - ArgE = MTE->getSubExpr(); - IsTemporary = true; - } + if (HasRewrittenInit) { + for (auto *N : PreVisit) { + ProgramStateRef state = N->getState(); + const LocationContext *LCtx = N->getLocationContext(); + state = state->BindExpr(S, LCtx, state->getSVal(ArgE, LCtx)); + Bldr2.generateNode(S, N, state); + } + } else { + // If it's not rewritten, the contents of these expressions are not + // actually part of the current function, so we fall back to constant + // evaluation. + bool IsTemporary = false; + if (const auto *MTE = dyn_cast(ArgE)) { + ArgE = MTE->getSubExpr(); + IsTemporary = true; + } + + std::optional ConstantVal = svalBuilder.getConstantVal(ArgE); + const LocationContext *LCtx = Pred->getLocationContext(); + for (auto *I : PreVisit) { + ProgramStateRef State = I->getState(); + State = State->BindExpr(S, LCtx, ConstantVal.value_or(UnknownVal())); + if (IsTemporary) + State = createTemporaryRegionIfNeeded(State, LCtx, cast(S), + cast(S)); - std::optional ConstantVal = svalBuilder.getConstantVal(ArgE); - if (!ConstantVal) - ConstantVal = UnknownVal(); - - const LocationContext *LCtx = Pred->getLocationContext(); - for (const auto I : PreVisit) { - ProgramStateRef State = I->getState(); - State = State->BindExpr(S, LCtx, *ConstantVal); - if (IsTemporary) - State = createTemporaryRegionIfNeeded(State, LCtx, - cast(S), - cast(S)); - Bldr2.generateNode(S, I, State); + Bldr2.generateNode(S, I, State); + } } getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index 929f25b95fa1f..dd5064d993e66 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -26,6 +26,7 @@ static_assert(foo[2][2] == nullptr, ""); static_assert(foo[2][3] == &m, ""); static_assert(foo[2][4] == nullptr, ""); +constexpr int ZeroSizeArray[] = {}; constexpr int SomeInt[] = {1}; constexpr int getSomeInt() { return *SomeInt; } @@ -53,6 +54,10 @@ constexpr int derefPtr(const int *d) { } static_assert(derefPtr(data) == 5, ""); +/// Make sure we can refer to the one-past-the-end element +/// and then return back to the end of the array. +static_assert((&data[5])[-1] == 1, ""); + constexpr int storePtr() { int b[] = {1,2,3,4}; int *c = b; @@ -595,3 +600,12 @@ int test_multiarray22() { } #endif + +namespace ArrayMemberAccess { + struct A { + int x; + }; + void f(const A (&a)[]) { + bool cond = a->x; + } +} diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp index fbe76aba73c90..0a17106449faf 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -900,7 +900,7 @@ namespace shufflevector { static_assert(vectorShuffle6[7] == 7, "");// ref-error {{not an integral constant expression}} constexpr vector4char vectorShuffleFail1 = __builtin_shufflevector( // both-error {{must be initialized by a constant expression}}\ - // ref-error {{index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position 0 not permitted in a constexpr context.}} + // ref-error {{index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position 0 is not permitted in a constexpr context}} vector4charConst1, vector4charConst2, -1, -1, -1, -1); } diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c index 2a75457a4693f..f4c7bf16f2f95 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -278,3 +278,15 @@ void addrlabelexpr(void) { a0: ; static void *ps[] = { &&a0 }; // pedantic-warning {{use of GNU address-of-label extension}} } + +extern void cv2; +void *foo5 (void) +{ + return &cv2; // pedantic-warning{{address of an expression of type 'void'}} +} + +__attribute__((weak)) const unsigned int test10_bound = 10; +char test10_global[test10_bound]; // all-error {{variable length array declaration not allowed at file scope}} +void test10(void) { + char test10_local[test10_bound] = "help"; // all-error {{variable-sized object may not be initialized}} +} diff --git a/clang/test/AST/Interp/cxx03.cpp b/clang/test/AST/Interp/cxx03.cpp index b6aaf0840cfb3..70ae4134842b5 100644 --- a/clang/test/AST/Interp/cxx03.cpp +++ b/clang/test/AST/Interp/cxx03.cpp @@ -24,3 +24,8 @@ namespace NonLValueMemberExpr { const int &TT1::subobj_init = PODType().value; } + +void LambdaAccessingADummy() { + int d; + int a9[1] = {[d = 0] = 1}; // both-error {{is not an integral constant expression}} +} diff --git a/clang/test/AST/Interp/cxx11.cpp b/clang/test/AST/Interp/cxx11.cpp index 993e3618a3784..f06a5dd173cba 100644 --- a/clang/test/AST/Interp/cxx11.cpp +++ b/clang/test/AST/Interp/cxx11.cpp @@ -30,3 +30,19 @@ constexpr S s = { 5 }; constexpr const int *p = &s.m + 1; constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; // ok + +constexpr int preDec(int x) { // both-error {{never produces a constant expression}} + return --x; // both-note {{subexpression}} +} + +constexpr int postDec(int x) { // both-error {{never produces a constant expression}} + return x--; // both-note {{subexpression}} +} + +constexpr int preInc(int x) { // both-error {{never produces a constant expression}} + return ++x; // both-note {{subexpression}} +} + +constexpr int postInc(int x) { // both-error {{never produces a constant expression}} + return x++; // both-note {{subexpression}} +} diff --git a/clang/test/AST/Interp/cxx98.cpp b/clang/test/AST/Interp/cxx98.cpp index be81735329db8..e68e4dbc8d74b 100644 --- a/clang/test/AST/Interp/cxx98.cpp +++ b/clang/test/AST/Interp/cxx98.cpp @@ -50,3 +50,7 @@ _Static_assert(c0_test == 0, ""); int a = 0; // both-note {{declared here}} _Static_assert(a == 0, ""); // both-error {{static assertion expression is not an integral constant expression}} \ // both-note {{read of non-const variable 'a' is not allowed in a constant expression}} + +struct SelfReference { SelfReference &r; }; +extern SelfReference self_reference_1; +SelfReference self_reference_2 = {self_reference_1}; diff --git a/clang/test/AST/Interp/eval-order.cpp b/clang/test/AST/Interp/eval-order.cpp index 695a43c9d235b..aaf2b74510bbf 100644 --- a/clang/test/AST/Interp/eval-order.cpp +++ b/clang/test/AST/Interp/eval-order.cpp @@ -1,8 +1,7 @@ -// RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu -// RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++1z -verify=ref,both %s -fcxx-exceptions -triple=x86_64-linux-gnu +// RUN: %clang_cc1 -std=c++1z -verify=expected,both %s -fcxx-exceptions -triple=x86_64-linux-gnu -fexperimental-new-constant-interpreter // ref-no-diagnostics -// expected-no-diagnostics /// Check that assignment operators evaluate their operands right-to-left. /// Copied from test/SemaCXX/constant-expression-cxx1z.cpp @@ -46,7 +45,7 @@ namespace EvalOrder { } template constexpr T &&b(T &&v) { if (!done_a) - throw "wrong"; + throw "wrong"; // expected-note 7{{not valid}} done_b = true; return (T &&)v; } @@ -76,21 +75,30 @@ namespace EvalOrder { // SEQ(A(&ud)->*B(&UserDefined::n)); FIXME // Rule 4: a(b1, b2, b3) - // SEQ(A(f)(B(1), B(2), B(3))); FIXME + SEQ(A(f)(B(1), B(2), B(3))); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} // Rule 5: b = a, b @= a - // SEQ(B(lvalue().get()) = A(0)); FIXME - // SEQ(B(lvalue().get()) = A(ud)); FIXME + SEQ(B(lvalue().get()) = A(0)); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} + SEQ(B(lvalue().get()) = A(ud)); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} SEQ(B(lvalue().get()) += A(0)); - // SEQ(B(lvalue().get()) += A(ud)); FIXME - // SEQ(B(lvalue().get()) += A(nm)); FIXME + SEQ(B(lvalue().get()) += A(ud)); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} + + SEQ(B(lvalue().get()) += A(nm)); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} + // Rule 6: a[b] constexpr int arr[3] = {}; SEQ(A(arr)[B(0)]); SEQ(A(+arr)[B(0)]); - // SEQ(A(0)[B(arr)]); FIXME - // SEQ(A(0)[B(+arr)]); FIXME + SEQ(A(0)[B(arr)]); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} + SEQ(A(0)[B(+arr)]); // expected-error {{not an integral constant expression}} FIXME \ + // expected-note 2{{in call to}} SEQ(A(ud)[B(0)]); // Rule 7: a << b diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index a5bb9f1a19aaa..10c62a43ef33b 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -617,3 +617,15 @@ namespace { void bir [[clang::annotate("B", {1, 2, 3, 4})]] (); // both-error {{'annotate' attribute requires parameter 1 to be a constant expression}} \ // both-note {{subexpression not valid in a constant expression}} } + +namespace FuncPtrParam { + void foo(int(&a)()) { + *a; // both-warning {{expression result unused}} + } +} + +namespace { + void f() noexcept; + void (&r)() = f; + void (&cond3)() = r; +} diff --git a/clang/test/AST/Interp/objc.mm b/clang/test/AST/Interp/objc.mm new file mode 100644 index 0000000000000..6402c8ae098fd --- /dev/null +++ b/clang/test/AST/Interp/objc.mm @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -verify=ref,both %s + +@interface A { + int a; + static_assert(a, ""); // both-error {{static assertion expression is not an integral constant expression}} +} +@end + +@interface NSString +@end +constexpr NSString *t0 = @"abc"; +constexpr NSString *t1 = @("abc"); diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 41be9b71a27f9..0a89c81bafd57 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1335,8 +1335,6 @@ namespace UnnamedBitFields { static_assert(a.c == 'a', ""); } -/// FIXME: This still doesn't work in the new interpreter because -/// we lack type information for dummy pointers. namespace VirtualBases { /// This used to crash. namespace One { @@ -1346,7 +1344,7 @@ namespace VirtualBases { }; class B : public virtual A { public: - int getX() { return x; } // ref-note {{declared here}} + int getX() { return x; } // both-note {{declared here}} }; class DV : virtual public B{}; @@ -1354,7 +1352,7 @@ namespace VirtualBases { void foo() { DV b; int a[b.getX()]; // both-warning {{variable length arrays}} \ - // ref-note {{non-constexpr function 'getX' cannot be used}} + // both-note {{non-constexpr function 'getX' cannot be used}} } } @@ -1459,3 +1457,26 @@ namespace TemporaryWithInvalidDestructor { // both-note {{in call to}} #endif } + +namespace IgnoredCtorWithZeroInit { + struct S { + int a; + }; + + bool get_status() { + return (S(), true); + } +} + +#if __cplusplus >= 202002L +namespace VirtOperator { + /// This used to crash because it's a virtual CXXOperatorCallExpr. + struct B { + virtual constexpr bool operator==(const B&) const { return true; } + }; + struct D : B { + constexpr bool operator==(const B&) const override{ return false; } // both-note {{operator}} + }; + constexpr bool cmp_base_derived = D() == D(); // both-warning {{ambiguous}} +} +#endif diff --git a/clang/test/AST/Interp/sycl.cpp b/clang/test/AST/Interp/sycl.cpp new file mode 100644 index 0000000000000..5c922eca58091 --- /dev/null +++ b/clang/test/AST/Interp/sycl.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify=both,ref -fsyntax-only -Wno-unused +// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify=both,expected -fsyntax-only -Wno-unused -fexperimental-new-constant-interpreter + +// both-no-diagnostics + +constexpr int a = 0; +constexpr const char *a_name = __builtin_sycl_unique_stable_name(decltype(a)); +static_assert(__builtin_strcmp(a_name, "_ZTSKi") == 0); + diff --git a/clang/test/AST/Interp/unions.cpp b/clang/test/AST/Interp/unions.cpp new file mode 100644 index 0000000000000..293a1981a52f0 --- /dev/null +++ b/clang/test/AST/Interp/unions.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -verify=ref,both %s + +union U { + int a; + int b; +}; + +constexpr U a = {12}; +static_assert(a.a == 12, ""); +static_assert(a.b == 0, ""); // both-error {{not an integral constant expression}} \ + // both-note {{read of member 'b' of union with active member 'a'}} +union U1 { + int i; + float f = 3.0f; +}; +constexpr U1 u1{}; +static_assert(u1.f == 3.0, ""); +static_assert(u1.i == 1, ""); // both-error {{not an integral constant expression}} \ + // both-note {{read of member 'i' of union with active member 'f'}} + + + +union A { + int a; + double d; +}; +constexpr A aa = {1, 2.0}; // both-error {{excess elements in union initializer}} +constexpr A ab = {.d = 1.0}; +static_assert(ab.d == 1.0, ""); +static_assert(ab.a == 1, ""); // both-error {{not an integral constant expression}} \ + // both-note {{read of member 'a' of union with active member 'd'}} + + +namespace Empty { + union E {}; + constexpr E e{}; +} + +namespace SimpleStore { + union A { + int a; + int b; + }; + constexpr int foo() { + A a{.b = 4}; + a.b = 10; + return a.b; + } + static_assert(foo() == 10, ""); + + constexpr int empty() { + A a{}; /// Just test that this works. + return 10; + } + static_assert(empty() == 10, ""); +} + +namespace ZeroInit { + struct S { int m; }; + union Z { + float f; + }; + + constexpr Z z{}; + static_assert(z.f == 0.0, ""); +} diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp index 554cdcf83fcdf..e062d4f068a40 100644 --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -459,7 +459,7 @@ namespace testClassTemplateDecl { // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-148]]:3, col:31> col:31 TestTemplateDefaultNonType{{$}} // CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} col:16 'int' depth 0 index 0 I{{$}} -// CHECK-NEXT: | `-TemplateArgument expr{{$}} +// CHECK-NEXT: | `-TemplateArgument expr{{$}} // CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} 'int' 42{{$}} // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:31 struct TestTemplateDefaultNonType{{$}} @@ -671,7 +671,7 @@ namespace TestNonTypeTemplateParmDecl { // CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl // CHECK-NEXT: FunctionTemplateDecl // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I -// CHECK-NEXT: TemplateArgument expr +// CHECK-NEXT: TemplateArgument {{.*}} expr // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J diff --git a/clang/test/AST/ast-dump-default-init-json.cpp b/clang/test/AST/ast-dump-default-init-json.cpp index 1058b4e3ea4d9..f4949a9c9eedf 100644 --- a/clang/test/AST/ast-dump-default-init-json.cpp +++ b/clang/test/AST/ast-dump-default-init-json.cpp @@ -789,10 +789,10 @@ void test() { // CHECK-NEXT: "valueCategory": "lvalue", // CHECK-NEXT: "extendingDecl": { // CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "FieldDecl", -// CHECK-NEXT: "name": "a", +// CHECK-NEXT: "kind": "VarDecl", +// CHECK-NEXT: "name": "b", // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "const A &" +// CHECK-NEXT: "qualType": "B" // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "storageDuration": "automatic", diff --git a/clang/test/AST/ast-dump-default-init.cpp b/clang/test/AST/ast-dump-default-init.cpp index 15b29f04bf21b..26864fbf15424 100644 --- a/clang/test/AST/ast-dump-default-init.cpp +++ b/clang/test/AST/ast-dump-default-init.cpp @@ -13,7 +13,7 @@ void test() { } // CHECK: -CXXDefaultInitExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue has rewritten init // CHECK-NEXT: `-ExprWithCleanups 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue -// CHECK-NEXT: `-MaterializeTemporaryExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue extended by Field 0x{{[^ ]*}} 'a' 'const A &' +// CHECK-NEXT: `-MaterializeTemporaryExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue extended by Var 0x{{[^ ]*}} 'b' 'B' // CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <{{.*}}> 'const A' // CHECK-NEXT: `-CXXFunctionalCastExpr 0x{{[^ ]*}} <{{.*}}> 'A' functional cast to A // CHECK-NEXT: `-InitListExpr 0x{{[^ ]*}} <{{.*}}> 'A' diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp index 4b7365e554cb7..dd2fe1fcf60cf 100644 --- a/clang/test/AST/ast-dump-expr-json.cpp +++ b/clang/test/AST/ast-dump-expr-json.cpp @@ -2333,7 +2333,7 @@ void TestNonADLCall3() { // CHECK-NEXT: "kind": "FunctionDecl", // CHECK-NEXT: "name": "operator delete", // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "void (void *) noexcept" +// CHECK-NEXT: "qualType": "void (void *, unsigned long) noexcept" // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "inner": [ diff --git a/clang/test/AST/ast-dump-expr.cpp b/clang/test/AST/ast-dump-expr.cpp index 604868103dab8..f9e9ee9d35dde 100644 --- a/clang/test/AST/ast-dump-expr.cpp +++ b/clang/test/AST/ast-dump-expr.cpp @@ -164,7 +164,7 @@ void UnaryExpressions(int *p) { // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' ::delete p; - // CHECK: CXXDeleteExpr 0x{{[^ ]*}} 'void' global Function 0x{{[^ ]*}} 'operator delete' 'void (void *) noexcept' + // CHECK: CXXDeleteExpr 0x{{[^ ]*}} 'void' global Function 0x{{[^ ]*}} 'operator delete' 'void (void *, unsigned long) noexcept' // CHECK-NEXT: ImplicitCastExpr // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' diff --git a/clang/test/AST/ast-dump-stmt-json.cpp b/clang/test/AST/ast-dump-stmt-json.cpp index 667a12a012024..a473d17da9424 100644 --- a/clang/test/AST/ast-dump-stmt-json.cpp +++ b/clang/test/AST/ast-dump-stmt-json.cpp @@ -994,7 +994,7 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "kind": "FunctionDecl", // CHECK-NEXT: "name": "operator delete", // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "void (void *) noexcept" +// CHECK-NEXT: "qualType": "void (void *, unsigned long) noexcept" // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "inner": [ @@ -1369,7 +1369,7 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "kind": "FunctionDecl", // CHECK-NEXT: "name": "operator delete", // CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "void (void *) noexcept" +// CHECK-NEXT: "qualType": "void (void *, unsigned long) noexcept" // CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "inner": [ @@ -1722,7 +1722,6 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, -// CHECK-NEXT: "isUsed": true, // CHECK-NEXT: "name": "operator delete", // CHECK-NEXT: "mangledName": "_ZdlPv", // CHECK-NEXT: "type": { @@ -1810,6 +1809,126 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: } +// CHECK-NOT: {{^}}Dumping +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "isUsed": true, +// CHECK-NEXT: "name": "operator delete", +// CHECK-NEXT: "mangledName": "_ZdlPvm", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void *, unsigned long) noexcept" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void *" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "unsigned long" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VisibilityAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true, +// CHECK-NEXT: "visibility": "default" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + +// CHECK-NOT: {{^}}Dumping +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "operator delete", +// CHECK-NEXT: "mangledName": "_ZdlPvmSt11align_val_t", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void *, unsigned long, std::align_val_t) noexcept" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void *" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "unsigned long" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "std::align_val_t" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VisibilityAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true, +// CHECK-NEXT: "visibility": "default" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + // CHECK-NOT: {{^}}Dumping // CHECK: "kind": "FunctionDecl", // CHECK-NEXT: "loc": {}, @@ -1906,6 +2025,125 @@ void TestDependentGenericSelectionExpr(Ty T) { // CHECK-NEXT: } +// CHECK-NOT: {{^}}Dumping +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "operator delete[]", +// CHECK-NEXT: "mangledName": "_ZdaPvm", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void *, unsigned long) noexcept" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void *" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "unsigned long" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VisibilityAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true, +// CHECK-NEXT: "visibility": "default" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + +// CHECK-NOT: {{^}}Dumping +// CHECK: "kind": "FunctionDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "operator delete[]", +// CHECK-NEXT: "mangledName": "_ZdaPvmSt11align_val_t", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (void *, unsigned long, std::align_val_t) noexcept" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void *" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "unsigned long" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": {}, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "std::align_val_t" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "VisibilityAttr", +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} +// CHECK-NEXT: }, +// CHECK-NEXT: "implicit": true, +// CHECK-NEXT: "visibility": "default" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + // CHECK-NOT: {{^}}Dumping // CHECK: "kind": "FunctionTemplateDecl", // CHECK-NEXT: "loc": { diff --git a/clang/test/AST/ast-print-openacc-compute-construct.cpp b/clang/test/AST/ast-print-openacc-compute-construct.cpp index 19965e7491414..fe580c86ac8ea 100644 --- a/clang/test/AST/ast-print-openacc-compute-construct.cpp +++ b/clang/test/AST/ast-print-openacc-compute-construct.cpp @@ -130,5 +130,33 @@ void foo() { //CHECK: #pragma acc parallel device_type(SomeStructImpl) #pragma acc parallel device_type (SomeStructImpl) while(true); + +//CHECK: #pragma acc parallel reduction(+: iPtr) +#pragma acc parallel reduction(+: iPtr) + while(true); +//CHECK: #pragma acc parallel reduction(*: i) +#pragma acc parallel reduction(*: i) + while(true); +//CHECK: #pragma acc parallel reduction(max: SomeB) +#pragma acc parallel reduction(max: SomeB) + while(true); +//CHECK: #pragma acc parallel reduction(min: iPtr) +#pragma acc parallel reduction(min: iPtr) + while(true); +//CHECK: #pragma acc parallel reduction(&: i) +#pragma acc parallel reduction(&: i) + while(true); +//CHECK: #pragma acc parallel reduction(|: SomeB) +#pragma acc parallel reduction(|: SomeB) + while(true); +//CHECK: #pragma acc parallel reduction(^: iPtr) +#pragma acc parallel reduction(^: iPtr) + while(true); +//CHECK: #pragma acc parallel reduction(&&: i) +#pragma acc parallel reduction(&&: i) + while(true); +//CHECK: #pragma acc parallel reduction(||: SomeB) +#pragma acc parallel reduction(||: SomeB) + while(true); } diff --git a/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c b/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c new file mode 100644 index 0000000000000..a585a45eeff03 --- /dev/null +++ b/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -fexperimental-late-parse-attributes %s -ast-dump | FileCheck %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct size_known { + int field; +}; + +//============================================================================== +// __counted_by on struct member pointer in decl attribute position +//============================================================================== + +struct on_member_pointer_complete_ty { + struct size_known *buf __counted_by(count); + int count; +}; +// CHECK-LABEL: struct on_member_pointer_complete_ty definition +// CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __counted_by(count)':'struct size_known *' +// CHECK-NEXT: `-FieldDecl {{.*}} referenced count 'int' + +struct on_pointer_anon_count { + struct size_known *buf __counted_by(count); + struct { + int count; + }; +}; + +// CHECK-LABEL: struct on_pointer_anon_count definition +// CHECK-NEXT: |-FieldDecl {{.*}} buf 'struct size_known * __counted_by(count)':'struct size_known *' +// CHECK-NEXT: |-RecordDecl {{.*}} struct definition +// CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' +// CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' +// CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' +// CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' +// CHECK-NEXT: `-Field {{.*}} 'count' 'int' + +//============================================================================== +// __counted_by on struct member pointer in type attribute position +//============================================================================== +// TODO: Correctly parse counted_by as a type attribute. Currently it is parsed +// as a declaration attribute and is **not** late parsed resulting in the `count` +// field being unavailable. +// +// See `clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c` for test +// cases. diff --git a/clang/test/AST/attr-counted-by-struct-ptrs.c b/clang/test/AST/attr-counted-by-struct-ptrs.c new file mode 100644 index 0000000000000..79a453d239cd5 --- /dev/null +++ b/clang/test/AST/attr-counted-by-struct-ptrs.c @@ -0,0 +1,117 @@ +// RUN: %clang_cc1 %s -ast-dump | FileCheck %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct size_unknown; +struct size_known { + int field; +}; + +//============================================================================== +// __counted_by on struct member pointer in decl attribute position +//============================================================================== + +// CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *' +struct on_member_pointer_complete_ty { + int count; + struct size_known * buf __counted_by(count); +}; + +// CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: |-RecordDecl {{.+}} struct definition +// CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *' +// CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' +// CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by(count)':'struct size_known *' +// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' +// CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by(count)':'struct size_known *' +struct on_pointer_anon_buf { + int count; + struct { + struct size_known *buf __counted_by(count); + }; +}; + +struct on_pointer_anon_count { + struct { + int count; + }; + struct size_known *buf __counted_by(count); +}; + +//============================================================================== +// __counted_by on struct member pointer in type attribute position +//============================================================================== +// TODO: Correctly parse counted_by as a type attribute. Currently it is parsed +// as a declaration attribute + +// CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_complete_ty_ty_pos definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *' +struct on_member_pointer_complete_ty_ty_pos { + int count; + struct size_known *__counted_by(count) buf; +}; + +// TODO: This should be forbidden but isn't due to counted_by being treated as a +// declaration attribute. The attribute ends up on the outer most pointer +// (allowed by sema) even though syntactically its supposed to be on the inner +// pointer (would not allowed by sema due to pointee being a function type). +// CHECK-LABEL: RecordDecl {{.+}} struct on_member_pointer_fn_ptr_ty_ty_pos_inner definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: `-FieldDecl {{.+}} fn_ptr 'void (** __counted_by(count))(void)':'void (**)(void)' +struct on_member_pointer_fn_ptr_ty_ty_pos_inner { + int count; + void (* __counted_by(count) * fn_ptr)(void); +}; + +// FIXME: The generated AST here is wrong. The attribute should be on the inner +// pointer. +// CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_inner definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __counted_by(count)':'struct size_known **' +struct on_nested_pointer_inner { + int count; + // TODO: This should be disallowed because in the `-fbounds-safety` model + // `__counted_by` can only be nested when used in function parameters. + struct size_known *__counted_by(count) *buf; +}; + +// CHECK-LABEL: RecordDecl {{.+}} struct on_nested_pointer_outer definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: `-FieldDecl {{.+}} buf 'struct size_known ** __counted_by(count)':'struct size_known **' +struct on_nested_pointer_outer { + int count; + struct size_known **__counted_by(count) buf; +}; + +// CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_buf_ty_pos definition +// CHECK-NEXT: |-FieldDecl {{.+}} referenced count 'int' +// CHECK-NEXT: |-RecordDecl {{.+}} struct definition +// CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *' +// CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' +// CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by(count)':'struct size_known *' +// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' +// CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by(count)':'struct size_known *' +struct on_pointer_anon_buf_ty_pos { + int count; + struct { + struct size_known * __counted_by(count) buf; + }; +}; + +// CHECK-LABEL: RecordDecl {{.+}} struct on_pointer_anon_count_ty_pos definition +// CHECK-NEXT: |-RecordDecl {{.+}} struct definition +// CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' +// CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' +// CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' +// CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' +// CHECK-NEXT: | `-Field {{.+}} 'count' 'int' +struct on_pointer_anon_count_ty_pos { + struct { + int count; + }; + struct size_known *__counted_by(count) buf; +}; diff --git a/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-ref-deref-on-diff-classes.cpp b/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-ref-deref-on-diff-classes.cpp index aac58c0c1dda6..85108bccfee71 100644 --- a/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-ref-deref-on-diff-classes.cpp +++ b/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-ref-deref-on-diff-classes.cpp @@ -19,4 +19,5 @@ struct Derived : Base { }; void foo () { Derived d; + d.deref(); } diff --git a/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-templates.cpp b/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-templates.cpp index eeb62d5d89ec4..4fc1624d7a154 100644 --- a/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-templates.cpp +++ b/clang/test/Analysis/Checkers/WebKit/ref-cntbl-base-virtual-dtor-templates.cpp @@ -10,8 +10,7 @@ struct DerivedClassTmpl1 : T { }; // expected-warning@-1{{Struct 'RefCntblBase' is used as a base of struct 'DerivedClassTmpl1' but doesn't have virtual destructor}} DerivedClassTmpl1 a; - - +void foo(DerivedClassTmpl1& obj) { obj.deref(); } template struct DerivedClassTmpl2 : T { }; @@ -21,7 +20,6 @@ template int foo(T) { DerivedClassTmpl2 f; return 42; } int b = foo(RefCntblBase{}); - template struct DerivedClassTmpl3 : T { }; // expected-warning@-1{{Struct 'RefCntblBase' is used as a base of struct 'DerivedClassTmpl3' but doesn't have virtual destructor}} @@ -29,7 +27,6 @@ struct DerivedClassTmpl3 : T { }; typedef DerivedClassTmpl3 Foo; Foo c; - namespace WTF { class RefCountedBase { @@ -58,33 +55,344 @@ class RefCounted : public RefCountedBase { RefCounted() { } }; +template +class ExoticRefCounted : public RefCountedBase { +public: + void deref() const { + if (derefBase()) + delete (const_cast(static_cast(this))); + } +}; + +template +class BadBase : RefCountedBase { +public: + void deref() const { + if (derefBase()) + delete (const_cast(static_cast(this))); + } +}; + +template +class FancyDeref { +public: + void ref() const + { + ++refCount; + } + + void deref() const + { + --refCount; + if (refCount) + return; + auto deleteThis = [this] { + delete static_cast(this); + }; + deleteThis(); + } +private: + mutable unsigned refCount { 0 }; +}; + +namespace Detail { + + template + class CallableWrapperBase { + public: + virtual ~CallableWrapperBase() { } + virtual Out call(In...) = 0; + }; + + template class CallableWrapper; + + template + class CallableWrapper : public CallableWrapperBase { + public: + explicit CallableWrapper(CallableType&& callable) + : m_callable(WTFMove(callable)) { } + CallableWrapper(const CallableWrapper&) = delete; + CallableWrapper& operator=(const CallableWrapper&) = delete; + Out call(In... in) final { return m_callable(in...); } + private: + CallableType m_callable; + }; + +} // namespace Detail + +template class Function; + +template +class Function { +public: + using Impl = Detail::CallableWrapperBase; + + Function() = default; + + template + Function(CallableType&& callable) + : m_callableWrapper(new Detail::CallableWrapper>(callable)) { } + + template + Function(FunctionType f) + : m_callableWrapper(new Detail::CallableWrapper>(f)) { } + + ~Function() { + } + + Out operator()(In... in) const { + ASSERT(m_callableWrapper); + return m_callableWrapper->call(in...); + } + + explicit operator bool() const { return !!m_callableWrapper; } + +private: + Impl* m_callableWrapper; +}; + +void ensureOnMainThread(const Function&& function); + +enum class DestructionThread { Any, MainThread }; + +template +class FancyDeref2 { +public: + void ref() const + { + ++refCount; + } + + void deref() const + { + --refCount; + if (refCount) + return; + const_cast*>(this)->destroy(); + } + +private: + void destroy() { + delete static_cast(this); + } + mutable unsigned refCount { 0 }; +}; + +template +class DerivedFancyDeref2 : public FancyDeref2 { +}; + +template +class BadFancyDeref { +public: + void ref() const + { + ++refCount; + } + + void deref() const + { + --refCount; + if (refCount) + return; + auto deleteThis = [this] { + delete static_cast(this); + }; + delete this; + } +private: + mutable unsigned refCount { 0 }; +}; + template class ThreadSafeRefCounted { public: - void ref() const; - bool deref() const; + void ref() const { ++refCount; } + void deref() const { + if (!--refCount) + delete const_cast(static_cast(this)); + } +private: + mutable unsigned refCount { 0 }; }; template class ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr { public: - void ref() const; - bool deref() const; + void ref() const { ++refCount; } + void deref() const { + if (!--refCount) + delete const_cast(static_cast(this)); + } +private: + mutable unsigned refCount { 0 }; }; } // namespace WTF class DerivedClass4 : public WTF::RefCounted { }; +class DerivedClass4b : public WTF::ExoticRefCounted { }; + +class DerivedClass4cSub; +class DerivedClass4c : public WTF::BadBase { }; +// expected-warning@-1{{Class 'WTF::BadBase' is used as a base of class 'DerivedClass4c' but doesn't have virtual destructor}} +class DerivedClass4cSub : public DerivedClass4c { }; +void UseDerivedClass4c(DerivedClass4c &obj) { obj.deref(); } + +class DerivedClass4d : public WTF::RefCounted { +public: + virtual ~DerivedClass4d() { } +}; +class DerivedClass4dSub : public DerivedClass4d { }; + class DerivedClass5 : public DerivedClass4 { }; // expected-warning@-1{{Class 'DerivedClass4' is used as a base of class 'DerivedClass5' but doesn't have virtual destructor}} +void UseDerivedClass5(DerivedClass5 &obj) { obj.deref(); } class DerivedClass6 : public WTF::ThreadSafeRefCounted { }; +void UseDerivedClass6(DerivedClass6 &obj) { obj.deref(); } class DerivedClass7 : public DerivedClass6 { }; // expected-warning@-1{{Class 'DerivedClass6' is used as a base of class 'DerivedClass7' but doesn't have virtual destructor}} +void UseDerivedClass7(DerivedClass7 &obj) { obj.deref(); } class DerivedClass8 : public WTF::ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr { }; +void UseDerivedClass8(DerivedClass8 &obj) { obj.deref(); } class DerivedClass9 : public DerivedClass8 { }; // expected-warning@-1{{Class 'DerivedClass8' is used as a base of class 'DerivedClass9' but doesn't have virtual destructor}} +void UseDerivedClass9(DerivedClass9 &obj) { obj.deref(); } + +class DerivedClass10 : public WTF::FancyDeref { }; +void UseDerivedClass10(DerivedClass10 &obj) { obj.deref(); } + +class DerivedClass10b : public WTF::DerivedFancyDeref2 { }; +void UseDerivedClass10b(DerivedClass10b &obj) { obj.deref(); } + +class DerivedClass10c : public WTF::BadFancyDeref { }; +// expected-warning@-1{{Class 'WTF::BadFancyDeref' is used as a base of class 'DerivedClass10c' but doesn't have virtual destructor}} +void UseDerivedClass10c(DerivedClass10c &obj) { obj.deref(); } + +class BaseClass1 { +public: + void ref() const { ++refCount; } + void deref() const; +private: + enum class Type { Base, Derived } type { Type::Base }; + mutable unsigned refCount { 0 }; +}; + +class DerivedClass11 : public BaseClass1 { }; + +void BaseClass1::deref() const +{ + --refCount; + if (refCount) + return; + switch (type) { + case Type::Base: + delete const_cast(this); + break; + case Type::Derived: + delete const_cast(static_cast(this)); + break; + } +} + +void UseDerivedClass11(DerivedClass11& obj) { obj.deref(); } + +class BaseClass2; +static void deleteBase2(BaseClass2*); + +class BaseClass2 { +public: + void ref() const { ++refCount; } + void deref() const + { + if (!--refCount) + deleteBase2(const_cast(this)); + } + virtual bool isDerived() { return false; } +private: + mutable unsigned refCount { 0 }; +}; + +class DerivedClass12 : public BaseClass2 { + bool isDerived() final { return true; } +}; + +void UseDerivedClass11(DerivedClass12& obj) { obj.deref(); } + +void deleteBase2(BaseClass2* obj) { + if (obj->isDerived()) + delete static_cast(obj); + else + delete obj; +} + +class BaseClass3 { +public: + void ref() const { ++refCount; } + void deref() const + { + if (!--refCount) + const_cast(this)->destory(); + } + virtual bool isDerived() { return false; } + +private: + void destory(); + + mutable unsigned refCount { 0 }; +}; + +class DerivedClass13 : public BaseClass3 { + bool isDerived() final { return true; } +}; + +void UseDerivedClass11(DerivedClass13& obj) { obj.deref(); } + +void BaseClass3::destory() { + if (isDerived()) + delete static_cast(this); + else + delete this; +} + +class RecursiveBaseClass { +public: + void ref() const { + if (otherObject) + otherObject->ref(); + else + ++refCount; + } + void deref() const { + if (otherObject) + otherObject->deref(); + else { + --refCount; + if (refCount) + return; + delete this; + } + } +private: + RecursiveBaseClass* otherObject { nullptr }; + mutable unsigned refCount { 0 }; +}; + +class RecursiveDerivedClass : public RecursiveBaseClass { }; +// expected-warning@-1{{Class 'RecursiveBaseClass' is used as a base of class 'RecursiveDerivedClass' but doesn't have virtual destructor}} + +class DerivedClass14 : public WTF::RefCounted { +public: + virtual ~DerivedClass14() { } +}; + +void UseDerivedClass14(DerivedClass14& obj) { obj.deref(); } + +class DerivedClass15 : public DerivedClass14 { }; + +void UseDerivedClass15(DerivedClass15& obj) { obj.deref(); } diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp index 632a82eb0d8d1..25776870dd3ae 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp @@ -216,3 +216,76 @@ void foo() { } } // namespace conditional_op + +namespace local_assignment_basic { + +RefCountable *provide_ref_cntbl(); + +void foo(RefCountable* a) { + RefCountable* b = a; + // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + if (b->trivial()) + b = provide_ref_cntbl(); +} + +void bar(RefCountable* a) { + RefCountable* b; + // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + b = provide_ref_cntbl(); +} + +void baz() { + RefPtr a = provide_ref_cntbl(); + { + RefCountable* b = a.get(); + // expected-warning@-1{{Local variable 'b' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + b = provide_ref_cntbl(); + } +} + +} // namespace local_assignment_basic + +namespace local_assignment_to_parameter { + +RefCountable *provide_ref_cntbl(); +void someFunction(); + +void foo(RefCountable* a) { + a = provide_ref_cntbl(); + // expected-warning@-1{{Assignment to an uncounted parameter 'a' is unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + someFunction(); + a->method(); +} + +} // namespace local_assignment_to_parameter + +namespace local_assignment_to_static_local { + +RefCountable *provide_ref_cntbl(); +void someFunction(); + +void foo() { + static RefCountable* a = nullptr; + // expected-warning@-1{{Static local variable 'a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + a = provide_ref_cntbl(); + someFunction(); + a->method(); +} + +} // namespace local_assignment_to_static_local + +namespace local_assignment_to_global { + +RefCountable *provide_ref_cntbl(); +void someFunction(); + +RefCountable* g_a = nullptr; +// expected-warning@-1{{Global variable 'local_assignment_to_global::g_a' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + +void foo() { + g_a = provide_ref_cntbl(); + someFunction(); + g_a->method(); +} + +} // namespace local_assignment_to_global diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp index 96986631726fe..a98c6eb9c84d9 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp @@ -231,6 +231,18 @@ class RefCounted { void method(); void someFunction(); int otherFunction(); + unsigned recursiveTrivialFunction(int n) { return !n ? 1 : recursiveTrivialFunction(n - 1); } + unsigned recursiveComplexFunction(int n) { return !n ? otherFunction() : recursiveComplexFunction(n - 1); } + unsigned mutuallyRecursiveFunction1(int n) { return n < 0 ? 1 : (n % 2 ? mutuallyRecursiveFunction2(n - 2) : mutuallyRecursiveFunction1(n - 1)); } + unsigned mutuallyRecursiveFunction2(int n) { return n < 0 ? 1 : (n % 3 ? mutuallyRecursiveFunction2(n - 3) : mutuallyRecursiveFunction1(n - 2)); } + unsigned mutuallyRecursiveFunction3(int n) { return n < 0 ? 1 : (n % 5 ? mutuallyRecursiveFunction3(n - 5) : mutuallyRecursiveFunction4(n - 3)); } + unsigned mutuallyRecursiveFunction4(int n) { return n < 0 ? 1 : (n % 7 ? otherFunction() : mutuallyRecursiveFunction3(n - 3)); } + unsigned recursiveFunction5(unsigned n) { return n > 100 ? 2 : (n % 2 ? recursiveFunction5(n + 1) : recursiveFunction6(n + 2)); } + unsigned recursiveFunction6(unsigned n) { return n > 100 ? 3 : (n % 2 ? recursiveFunction6(n % 7) : recursiveFunction7(n % 5)); } + unsigned recursiveFunction7(unsigned n) { return n > 100 ? 5 : recursiveFunction7(n * 5); } + + void mutuallyRecursive8() { mutuallyRecursive9(); someFunction(); } + void mutuallyRecursive9() { mutuallyRecursive8(); } int trivial1() { return 123; } float trivial2() { return 0.3; } @@ -498,6 +510,24 @@ class UnrelatedClass { RefCounted::singleton().trivial18(); // no-warning RefCounted::singleton().someFunction(); // no-warning + getFieldTrivial().recursiveTrivialFunction(7); // no-warning + getFieldTrivial().recursiveComplexFunction(9); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().mutuallyRecursiveFunction1(11); // no-warning + getFieldTrivial().mutuallyRecursiveFunction2(13); // no-warning + getFieldTrivial().mutuallyRecursiveFunction3(17); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().mutuallyRecursiveFunction4(19); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().recursiveFunction5(23); // no-warning + getFieldTrivial().recursiveFunction6(29); // no-warning + getFieldTrivial().recursiveFunction7(31); // no-warning + + getFieldTrivial().mutuallyRecursive8(); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().mutuallyRecursive9(); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + getFieldTrivial().someFunction(); // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} getFieldTrivial().nonTrivial1(); diff --git a/clang/test/Analysis/cert/pos34-c-fp-suppression.cpp b/clang/test/Analysis/cert/pos34-c-fp-suppression.cpp deleted file mode 100644 index d982fcb8a1baf..0000000000000 --- a/clang/test/Analysis/cert/pos34-c-fp-suppression.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_analyze_cc1 \ -// RUN: -analyzer-checker=alpha.security.cert.pos.34c\ -// RUN: -verify %s - -#include "../Inputs/system-header-simulator.h" -void free(void *memblock); -void *malloc(size_t size); -int putenv(char *); -int rand(); - -namespace test_auto_var_used_good { - -extern char *ex; -int test_extern() { - return putenv(ex); // no-warning: extern storage class. -} - -void foo(void) { - char *buffer = (char *)"huttah!"; - if (rand() % 2 == 0) { - buffer = (char *)malloc(5); - strcpy(buffer, "woot"); - } - putenv(buffer); -} - -void bar(void) { - char *buffer = (char *)malloc(5); - strcpy(buffer, "woot"); - - if (rand() % 2 == 0) { - free(buffer); - buffer = (char *)"blah blah blah"; - } - putenv(buffer); -} - -void baz() { - char env[] = "NAME=value"; - // TODO: False Positive - putenv(env); - // expected-warning@-1 {{The 'putenv' function should not be called with arguments that have automatic storage}} - - /* - DO SOMETHING - */ - - putenv((char *)"NAME=anothervalue"); -} - -} // namespace test_auto_var_used_good diff --git a/clang/test/Analysis/cert/pos34-c.cpp b/clang/test/Analysis/cert/pos34-c.cpp deleted file mode 100644 index f2bd7b393d889..0000000000000 --- a/clang/test/Analysis/cert/pos34-c.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// RUN: %clang_analyze_cc1 \ -// RUN: -analyzer-checker=alpha.security.cert.pos.34c\ -// RUN: -verify %s - -// Examples from the CERT rule's page. -// https://wiki.sei.cmu.edu/confluence/x/6NYxBQ - -#include "../Inputs/system-header-simulator.h" -void free(void *memblock); -void *malloc(size_t size); -int putenv(char *); -int snprintf(char *str, size_t size, const char *format, ...); - -namespace test_auto_var_used_bad { - -int volatile_memory1(const char *var) { - char env[1024]; - int retval = snprintf(env, sizeof(env), "TEST=%s", var); - if (retval < 0 || (size_t)retval >= sizeof(env)) { - /* Handle error */ - } - - return putenv(env); - // expected-warning@-1 {{The 'putenv' function should not be called with arguments that have automatic storage}} -} - -} // namespace test_auto_var_used_bad - -namespace test_auto_var_used_good { - -int test_static(const char *var) { - static char env[1024]; - - int retval = snprintf(env, sizeof(env), "TEST=%s", var); - if (retval < 0 || (size_t)retval >= sizeof(env)) { - /* Handle error */ - } - - return putenv(env); -} - -int test_heap_memory(const char *var) { - static char *oldenv; - const char *env_format = "TEST=%s"; - const size_t len = strlen(var) + strlen(env_format); - char *env = (char *)malloc(len); - if (env == NULL) { - return -1; - } - if (putenv(env) != 0) { // no-warning: env was dynamically allocated. - free(env); - return -1; - } - if (oldenv != NULL) { - free(oldenv); /* avoid memory leak */ - } - oldenv = env; - return 0; -} - -} // namespace test_auto_var_used_good diff --git a/clang/test/Analysis/cxx-uninitialized-object.cpp b/clang/test/Analysis/cxx-uninitialized-object.cpp index e3fa8ae8d7f29..aee0dae15fbfa 100644 --- a/clang/test/Analysis/cxx-uninitialized-object.cpp +++ b/clang/test/Analysis/cxx-uninitialized-object.cpp @@ -1114,27 +1114,27 @@ void fCXX11MemberInitTest1() { CXX11MemberInitTest1(); } +#ifdef PEDANTIC struct CXX11MemberInitTest2 { struct RecordType { - // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}} - int a; // no-note - // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}} - int b; // no-note + int a; // expected-note {{uninitialized field 'this->a'}} + int b; // expected-note {{uninitialized field 'this->b'}} RecordType(int) {} }; - RecordType rec = RecordType(int()); + RecordType rec = RecordType(int()); // expected-warning {{2 uninitialized fields}} int dontGetFilteredByNonPedanticMode = 0; CXX11MemberInitTest2() {} }; void fCXX11MemberInitTest2() { - // TODO: we'd expect the warning: {{2 uninitializeds field}} CXX11MemberInitTest2(); // no-warning } +#endif // PEDANTIC + //===----------------------------------------------------------------------===// // "Esoteric" primitive type tests. //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/cxxnewexpr-callback.cpp b/clang/test/Analysis/cxxnewexpr-callback.cpp index fe7a9fffad93d..7df58cfa9ca28 100644 --- a/clang/test/Analysis/cxxnewexpr-callback.cpp +++ b/clang/test/Analysis/cxxnewexpr-callback.cpp @@ -9,7 +9,7 @@ void free(void *); } // namespace std void *operator new(size_t size) { return std::malloc(size); } -void operator delete(void *ptr) { std::free(ptr); } +void operator delete(void *ptr, size_t size) { std::free(ptr); } struct S { S() {} @@ -49,7 +49,7 @@ void test() { // CHECK-NEXT: PostCall (operator delete) } -void operator delete(void *ptr) { +void operator delete(void *ptr, size_t size) { std::free(ptr); // CHECK-NO-INLINE-NEXT: PreCall (std::free) // CHECK-NO-INLINE-NEXT: PostCall (std::free) diff --git a/clang/test/Analysis/lifetime-extended-regions.cpp b/clang/test/Analysis/lifetime-extended-regions.cpp index 4e98bd4b0403e..524f4e0c400d1 100644 --- a/clang/test/Analysis/lifetime-extended-regions.cpp +++ b/clang/test/Analysis/lifetime-extended-regions.cpp @@ -120,11 +120,11 @@ void aggregateWithReferences() { clang_analyzer_dump(viaReference); // expected-warning-re {{&lifetime_extended_object{RefAggregate, viaReference, S{{[0-9]+}}} }} clang_analyzer_dump(viaReference.rx); // expected-warning-re {{&lifetime_extended_object{int, viaReference, S{{[0-9]+}}} }} clang_analyzer_dump(viaReference.ry); // expected-warning-re {{&lifetime_extended_object{Composite, viaReference, S{{[0-9]+}}} }} - - // clang does not currently implement extending lifetime of object bound to reference members of aggregates, - // that are created from default member initializer (see `warn_unsupported_lifetime_extension` from `-Wdangling`) - RefAggregate defaultInitExtended{i}; // clang-bug does not extend `Composite` - clang_analyzer_dump(defaultInitExtended.ry); // expected-warning {{Unknown }} + + // The lifetime lifetime of object bound to reference members of aggregates, + // that are created from default member initializer was extended. + RefAggregate defaultInitExtended{i}; + clang_analyzer_dump(defaultInitExtended.ry); // expected-warning-re {{&lifetime_extended_object{Composite, defaultInitExtended, S{{[0-9]+}}} }} } void lambda() { diff --git a/clang/test/Analysis/putenv-stack-array.c b/clang/test/Analysis/putenv-stack-array.c new file mode 100644 index 0000000000000..f28aed73031d3 --- /dev/null +++ b/clang/test/Analysis/putenv-stack-array.c @@ -0,0 +1,90 @@ +// RUN: %clang_analyze_cc1 \ +// RUN: -analyzer-checker=alpha.security.PutenvStackArray \ +// RUN: -verify %s + +#include "Inputs/system-header-simulator.h" +void free(void *); +void *malloc(size_t); +int putenv(char *); +int snprintf(char *, size_t, const char *, ...); + +int test_auto_var(const char *var) { + char env[1024]; + (void)snprintf(env, sizeof(env), "TEST=%s", var); + return putenv(env); // expected-warning{{The 'putenv' function should not be called with arrays that have automatic storage}} +} + +int test_static_var(const char *var) { + static char env[1024]; + (void)snprintf(env, sizeof(env), "TEST=%s", var); + return putenv(env); // no-warning: static array is used +} + +void test_heap_memory(const char *var) { + const char *env_format = "TEST=%s"; + const size_t len = strlen(var) + strlen(env_format); + char *env = (char *)malloc(len); + if (env == NULL) + return; + if (putenv(env) != 0) // no-warning: env was dynamically allocated. + free(env); +} + +typedef struct { + int A; + char Env[1024]; +} Mem; + +int test_auto_var_struct() { + Mem mem; + return putenv(mem.Env); // expected-warning{{The 'putenv' function should not be called with}} +} + +int test_auto_var_subarray() { + char env[1024]; + return putenv(env + 100); // expected-warning{{The 'putenv' function should not be called with}} +} + +int f_test_auto_var_call(char *env) { + return putenv(env); // expected-warning{{The 'putenv' function should not be called with}} +} + +int test_auto_var_call() { + char env[1024]; + return f_test_auto_var_call(env); +} + +int test_constant() { + char *env = "TEST"; + return putenv(env); // no-warning: data is not on the stack +} + +extern char *ext_env; +int test_extern() { + return putenv(ext_env); // no-warning: extern storage class. +} + +void test_auto_var_reset() { + char env[] = "NAME=value"; + putenv(env); // expected-warning{{The 'putenv' function should not be called with}} + // ... (do something) + // Even cases like this are likely a bug: + // It looks like that if one string was passed to putenv, + // it should not be deallocated at all, because when reading the + // environment variable a pointer into this string is returned. + // In this case, if another (or the same) thread reads variable "NAME" + // at this point and does not copy the returned string, the data may + // become invalid. + putenv((char *)"NAME=anothervalue"); +} + +void f_main(char *env) { + putenv(env); // no warning: string allocated in stack of 'main' +} + +int main(int argc, char **argv) { + char env[] = "NAME=value"; + putenv(env); // no warning: string allocated in stack of 'main' + f_main(env); + return 0; +} diff --git a/clang/test/Analysis/setgid-setuid-order-notes.c b/clang/test/Analysis/setgid-setuid-order-notes.c new file mode 100644 index 0000000000000..03402413581c6 --- /dev/null +++ b/clang/test/Analysis/setgid-setuid-order-notes.c @@ -0,0 +1,73 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.SetgidSetuidOrder -analyzer-output=text -verify %s + +typedef int uid_t; +typedef int gid_t; + +int setuid(uid_t); +int setgid(gid_t); + +uid_t getuid(); +gid_t getgid(); + + + +void test_note_1() { + if (setuid(getuid()) == -1) // expected-note{{Assuming the condition is false}} \ + // expected-note{{Taking false branch}} + return; + if (setuid(getuid()) == -1) // expected-note{{Call to 'setuid' found here that removes superuser privileges}} \ + // expected-note{{Assuming the condition is false}} \ + // expected-note{{Taking false branch}} + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} \ + // expected-note{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; +} + +void test_note_2() { + if (setuid(getuid()) == -1) // expected-note{{Call to 'setuid' found here that removes superuser privileges}} \ + // expected-note 2 {{Assuming the condition is false}} \ + // expected-note 2 {{Taking false branch}} + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} \ + // expected-note{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} \ + // expected-note{{Assuming the condition is false}} \ + // expected-note{{Taking false branch}} + return; + if (setuid(getuid()) == -1) // expected-note{{Call to 'setuid' found here that removes superuser privileges}} \ + // expected-note{{Assuming the condition is false}} \ + // expected-note{{Taking false branch}} + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} \ + // expected-note{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; +} + +int f_setuid() { + return setuid(getuid()); // expected-note{{Call to 'setuid' found here that removes superuser privileges}} +} + +int f_setgid() { + return setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} \ + // expected-note{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} +} + +void test_note_3() { + if (f_setuid() == -1) // expected-note{{Assuming the condition is false}} \ + // expected-note{{Calling 'f_setuid'}} \ + // expected-note{{Returning from 'f_setuid'}} \ + // expected-note{{Taking false branch}} + return; + if (f_setgid() == -1) // expected-note{{Calling 'f_setgid'}} + return; +} + +void test_note_4() { + if (setuid(getuid()) == 0) { // expected-note{{Assuming the condition is true}} \ + // expected-note{{Call to 'setuid' found here that removes superuser privileges}} \ + // expected-note{{Taking true branch}} + if (setgid(getgid()) == 0) { // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} \ + // expected-note{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + } + } +} diff --git a/clang/test/Analysis/setgid-setuid-order.c b/clang/test/Analysis/setgid-setuid-order.c new file mode 100644 index 0000000000000..1c411aa6a27b5 --- /dev/null +++ b/clang/test/Analysis/setgid-setuid-order.c @@ -0,0 +1,257 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.SetgidSetuidOrder -verify %s + +typedef int uid_t; +typedef int gid_t; + +int setuid(uid_t); +int setgid(gid_t); +int seteuid(uid_t); +int setegid(gid_t); +int setreuid(uid_t, uid_t); +int setregid(gid_t, gid_t); +int setresuid(uid_t, uid_t, uid_t); +int setresgid(gid_t, gid_t, gid_t); + +uid_t getuid(); +gid_t getgid(); + + + +void correct_order() { + // A correct revocation sequence starts here. + if (setgid(getgid()) == -1) + return; + if (setuid(getuid()) == -1) + return; + // No warning for the following setgid statement. + // The previous setgid and setuid calls are a correct privilege revocation + // sequence. The checker does not care about the following statements (except + // if a wrong setuid-setgid sequence follows again). + if (setgid(getgid()) == -1) + return; +} + +void incorrect_after_correct() { + if (setgid(getgid()) == -1) + return; + if (setuid(getuid()) == -1) + return; + // Incorrect sequence starts here. + if (setuid(getuid()) == -1) + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; +} + +void incorrect_order() { + if (setuid(getuid()) == -1) + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; + if (setgid(getgid()) == -1) + return; +} + +void warn_at_second_time() { + if (setuid(getuid()) == -1) + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; + if (setuid(getuid()) == -1) + return; + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; +} + +uid_t f_uid(); +gid_t f_gid(); + +void setuid_other() { + if (setuid(f_uid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setgid_other() { + if (setuid(getuid()) == -1) + return; + if (setgid(f_gid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setuid_other_between() { + if (setuid(getuid()) == -1) + return; + if (setuid(f_uid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setgid_with_getuid() { + if (setuid(getuid()) == -1) + return; + // add a clang-tidy check for this case? + if (setgid(getuid()) == -1) + return; +} + +void setuid_with_getgid() { + // add a clang-tidy check for this case? + if (setuid(getgid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +int f_setuid() { + return setuid(getuid()); +} + +int f_setgid() { + return setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} +} + +void function_calls() { + if (f_setuid() == -1) + return; + if (f_setgid() == -1) + return; +} + +void seteuid_between() { + if (setuid(getuid()) == -1) + return; + if (seteuid(getuid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setegid_between() { + if (setuid(getuid()) == -1) + return; + if (setegid(getgid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setreuid_between() { + if (setuid(getuid()) == -1) + return; + if (setreuid(getuid(), getuid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setregid_between() { + if (setuid(getuid()) == -1) + return; + if (setregid(getgid(), getgid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setresuid_between() { + if (setuid(getuid()) == -1) + return; + if (setresuid(getuid(), getuid(), getuid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void setresgid_between() { + if (setuid(getuid()) == -1) + return; + if (setresgid(getgid(), getgid(), getgid()) == -1) + return; + if (setgid(getgid()) == -1) + return; +} + +void getgid_getuid_between() { + if (setuid(getuid()) == -1) + return; + (void)getgid(); + (void)getuid(); + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; +} + +void stored_getgid_getuid() { + // possible future improvement: detect this case + uid_t u = getuid(); + gid_t g = getgid(); + if (setuid(u) == -1) + return; + if (setgid(g) == -1) // no warning + return; +} + +void f_extern(); + +void other_unknown_function_between() { + if (setuid(getuid()) == -1) + return; + f_extern(); + if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; +} + +void setuid_error_case() { + if (setuid(getuid()) == -1) { + // No warning if we know that the first setuid call has failed. + (void)setgid(getgid()); + return; + } + (void)setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} +} + +void setuid_success_case() { + if (setuid(getuid()) == 0) { + if (setgid(getgid()) == 0) { // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + } + } +} + +void incorrect_order_compare_zero() { + if (setuid(getuid()) != 0) + return; + (void)setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} +} + +void setuid_error_case_compare_zero() { + if (setuid(getuid()) != 0) { + // No warning if we know that the first setuid call has failed. + (void)setgid(getgid()); + return; + } +} + +void incorrect_order_compare_other() { + if (setuid(getuid()) == -2) { + // This is a case for improvement: + // The checker does not recognize that this is an invalid error check, + // but this is really another type of bug not related to this checker. + (void)setgid(getgid()); // warning should appear here + return; + } + if (setgid(getgid()) == -2) { // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} + return; + } +} + +const int FAIL = -1; + +void incorrect_order_compare_var() { + if (setuid(getuid()) == FAIL) + return; + (void)setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}} +} diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index df34a5707da33..5fceb1d710334 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -170,7 +170,7 @@ configure_file(AST/gen_ast_dump_json_test.py ${CLANG_BINARY_DIR}/bin/gen_ast_dump_json_test.py COPYONLY) add_custom_target(clang-test-depends DEPENDS ${CLANG_TEST_DEPS}) -set_target_properties(clang-test-depends PROPERTIES FOLDER "Clang tests") +set_target_properties(clang-test-depends PROPERTIES FOLDER "Clang/Tests") add_lit_testsuite(check-clang "Running the Clang regression tests" ${CMAKE_CURRENT_BINARY_DIR} @@ -179,7 +179,6 @@ add_lit_testsuite(check-clang "Running the Clang regression tests" DEPENDS ${CLANG_TEST_DEPS} ARGS ${CLANG_TEST_EXTRA_ARGS} ) -set_target_properties(check-clang PROPERTIES FOLDER "Clang tests") add_lit_testsuites(CLANG ${CMAKE_CURRENT_SOURCE_DIR} PARAMS ${CLANG_TEST_PARAMS} @@ -190,7 +189,7 @@ add_lit_testsuites(CLANG ${CMAKE_CURRENT_SOURCE_DIR} # Add a legacy target spelling: clang-test add_custom_target(clang-test) add_dependencies(clang-test check-clang) -set_target_properties(clang-test PROPERTIES FOLDER "Clang tests") +set_target_properties(clang-test PROPERTIES FOLDER "Clang/Tests") # FIXME: This logic can be removed once all buildbots have moved # debuginfo-test from clang/test to llvm/projects or monorepo. diff --git a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp index 9e3210c6650f7..706549f56c52f 100644 --- a/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp +++ b/clang/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++1z -fsized-deallocation -fexceptions -verify %s +// RUN: %clang_cc1 -std=c++1z -fexceptions -verify %s using size_t = decltype(sizeof(0)); diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp index cf6b45ceabf2c..82ef871939d2c 100644 --- a/clang/test/CXX/drs/cwg16xx.cpp +++ b/clang/test/CXX/drs/cwg16xx.cpp @@ -483,8 +483,6 @@ namespace cwg1696 { // cwg1696: 7 const A &a = A(); // #cwg1696-D1-a }; D1 d1 = {}; // #cwg1696-d1 - // since-cxx14-warning@-1 {{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported; lifetime of temporary will end at the end of the full-expression}} - // since-cxx14-note@#cwg1696-D1-a {{initializing field 'a' with default member initializer}} struct D2 { const A &a = A(); // #cwg1696-D2-a diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index 35615076a6288..b71a81b62f814 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -206,19 +206,28 @@ namespace cwg1814 { // cwg1814: yes #endif } -namespace cwg1815 { // cwg1815: no +namespace cwg1815 { // cwg1815: 19 #if __cplusplus >= 201402L - // FIXME: needs codegen test - struct A { int &&r = 0; }; // #cwg1815-A + struct A { int &&r = 0; }; A a = {}; - // since-cxx14-warning@-1 {{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported; lifetime of temporary will end at the end of the full-expression}} FIXME - // since-cxx14-note@#cwg1815-A {{initializing field 'r' with default member initializer}} struct B { int &&r = 0; }; // #cwg1815-B // since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} // since-cxx14-note@#cwg1815-B {{initializing field 'r' with default member initializer}} // since-cxx14-note@#cwg1815-b {{in implicit default constructor for 'cwg1815::B' first required here}} B b; // #cwg1815-b + +#if __cplusplus >= 201703L + struct C { const int &r = 0; }; + constexpr C c = {}; // OK, since cwg1815 + static_assert(c.r == 0); + + constexpr int f() { + A a = {}; // OK, since cwg1815 + return a.r; + } + static_assert(f() == 0); +#endif #endif } diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp index 696cd1b9c84e7..8469a065ccaa0 100644 --- a/clang/test/CXX/drs/cwg28xx.cpp +++ b/clang/test/CXX/drs/cwg28xx.cpp @@ -109,3 +109,74 @@ struct A { #endif } // namespace cwg2858 + +namespace cwg2881 { // cwg2881: 19 tentatively ready 2024-04-19 + +#if __cplusplus >= 202302L + +template struct A : T {}; +template struct B : T {}; +template struct C : virtual T { C(T t) : T(t) {} }; +template struct D : virtual T { D(T t) : T(t) {} }; + +template +struct O1 : A, B { + using A::operator(); + using B::operator(); +}; + +template struct O2 : protected Ts { // expected-note {{declared protected here}} + using Ts::operator(); + O2(Ts ts) : Ts(ts) {} +}; + +template struct O3 : private Ts { // expected-note {{declared private here}} + using Ts::operator(); + O3(Ts ts) : Ts(ts) {} +}; + +// Not ambiguous because of virtual inheritance. +template +struct O4 : C, D { + using C::operator(); + using D::operator(); + O4(Ts t) : Ts(t), C(t), D(t) {} +}; + +// This still has a public path to the lambda, and it's also not +// ambiguous because of virtual inheritance. +template +struct O5 : private C, D { + using C::operator(); + using D::operator(); + O5(Ts t) : Ts(t), C(t), D(t) {} +}; + +// This is only invalid if we call T's call operator. +template +struct O6 : private T, U { // expected-note {{declared private here}} + using T::operator(); + using U::operator(); + O6(T t, U u) : T(t), U(u) {} +}; + +void f() { + int x; + auto L1 = [=](this auto&& self) { (void) &x; }; + auto L2 = [&](this auto&& self) { (void) &x; }; + O1{L1, L1}(); // expected-error {{inaccessible due to ambiguity}} + O1{L2, L2}(); // expected-error {{inaccessible due to ambiguity}} + O2{L1}(); // expected-error {{must derive publicly from the lambda}} + O3{L1}(); // expected-error {{must derive publicly from the lambda}} + O4{L1}(); + O5{L1}(); + O6 o{L1, L2}; + o.decltype(L1)::operator()(); // expected-error {{must derive publicly from the lambda}} + o.decltype(L1)::operator()(); // No error here because we've already diagnosed this method. + o.decltype(L2)::operator()(); +} + +#endif + +} // namespace cwg2881 + diff --git a/clang/test/CXX/drs/cwg292.cpp b/clang/test/CXX/drs/cwg292.cpp index b05d3b92d6275..a7bcbe6f50519 100644 --- a/clang/test/CXX/drs/cwg292.cpp +++ b/clang/test/CXX/drs/cwg292.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK -// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK -// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK -// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK -// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK -// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK -// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK +// RUN: %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,CXX98-11 +// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,CXX98-11 +// RUN: %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,SINCE-CXX14 +// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,SINCE-CXX14 +// RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,SINCE-CXX14 +// RUN: %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,SINCE-CXX14 +// RUN: %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -emit-llvm -disable-llvm-passes -o - -fexceptions -fcxx-exceptions -pedantic-errors | llvm-cxxfilt -n | FileCheck %s --check-prefixes CHECK,SINCE-CXX14 namespace cwg292 { // cwg292: 2.9 @@ -23,7 +23,8 @@ void f() { // CHECK: invoke {{.*}} i32 @cwg292::g()() // CHECK-NEXT: to {{.*}} unwind label %lpad // CHECK-LABEL: lpad: -// CHECK: call void @operator delete(void*)(ptr {{.*}} %[[CALL]]) +// CXX98-11: call void @operator delete(void*)(ptr {{.*}} %[[CALL]]) +// SINCE-CXX14: call void @operator delete(void*, unsigned long)(ptr {{.*}} %[[CALL]], i64 noundef 1) // CHECK-LABEL: eh.resume: // CHECK-LABEL: } diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p14.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p14.cpp index 6537cdcfeafa0..d0b24c8fe47b7 100644 --- a/clang/test/CXX/expr/expr.unary/expr.new/p14.cpp +++ b/clang/test/CXX/expr/expr.unary/expr.new/p14.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++1z -fsized-deallocation -fexceptions %s -verify +// RUN: %clang_cc1 -std=c++1z -fexceptions %s -verify using size_t = decltype(sizeof(0)); namespace std { enum class align_val_t : size_t {}; } diff --git a/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp b/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp index afd8ef05302fc..19f90801df31c 100644 --- a/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp +++ b/clang/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp @@ -33,6 +33,6 @@ template struct count_ints_2 { template // expected-note{{parameter pack 'Types' declared here}} struct count_types_2 { static const unsigned value = sizeof... Type; // expected-error{{missing parentheses around the size of parameter pack 'Type'}} \ - // expected-error{{Type' does not refer to the name of a parameter pack; did you mean 'Types'?}} + // expected-error{{'Type' does not refer to the name of a parameter pack; did you mean 'Types'?}} }; diff --git a/clang/test/CXX/special/class.temporary/p6.cpp b/clang/test/CXX/special/class.temporary/p6.cpp index 5554363cc69ab..a6d2adfd1fd2c 100644 --- a/clang/test/CXX/special/class.temporary/p6.cpp +++ b/clang/test/CXX/special/class.temporary/p6.cpp @@ -269,6 +269,40 @@ void init_capture_init_list() { // CHECK: } } +void check_dr1815() { // dr1815: yes +#if __cplusplus >= 201402L + + struct A { + int &&r = 0; + ~A() {} + }; + + struct B { + A &&a = A{}; + ~B() {} + }; + B a = {}; + + // CHECK: call {{.*}}block_scope_begin_function + extern void block_scope_begin_function(); + extern void block_scope_end_function(); + block_scope_begin_function(); + { + // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev + // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev + B b = {}; + } + // CHECK: call {{.*}}block_scope_end_function + block_scope_end_function(); + + // CHECK: call {{.*}}some_other_function + extern void some_other_function(); + some_other_function(); + // CHECK: call void @_ZZ12check_dr1815vEN1BD1Ev + // CHECK: call void @_ZZ12check_dr1815vEN1AD1Ev +#endif +} + namespace P2718R0 { namespace basic { template using T2 = std::list; diff --git a/clang/test/ClangScanDeps/response-file-clang-cl.c b/clang/test/ClangScanDeps/response-file-clang-cl.c new file mode 100644 index 0000000000000..b543231f4bb1b --- /dev/null +++ b/clang/test/ClangScanDeps/response-file-clang-cl.c @@ -0,0 +1,56 @@ +// Check that the scanner can adjust arguments by reading .rsp files in advance. + +// RUN: rm -rf %t +// RUN: split-file %s %t + +// First run the tests with a .cdb +// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json +// RUN: sed -e "s|DIR|%/t|g" %t/args_nested.template > %t/args_nested.rsp + +// RUN: cp %t/args_compilation.rsp %t/args.rsp +// RUN: clang-scan-deps --compilation-database %t/cdb.json > %t/deps.json +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// RUN: cp %t/args_preprocess.rsp %t/args.rsp +// RUN: clang-scan-deps --compilation-database %t/cdb.json > %t/deps.json +// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + + +// Now run the tests again with a in-place compilation database +// RUN: cd %t + +// RUN: cp args_compilation.rsp args.rsp +// RUN: clang-scan-deps -o deps.json -- %clang_cl @args.rsp +// RUN: cat deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// RUN: cp args_preprocess.rsp args.rsp +// RUN: clang-scan-deps -o deps.json -- %clang_cl @args.rsp +// RUN: cat deps.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s + +// Here we ensure that we got a qualified .obj with its full path, since that's what we're passing with /Fo +// CHECK: [[PREFIX]]/tu.obj: + +//--- cdb.json.template +[{ + "file": "DIR/tu.cpp", + "directory": "DIR", + "command": "clang-cl @DIR/args.rsp" +}] + +//--- args_compilation.rsp +@args_nested.rsp +/c + +//--- args_preprocess.rsp +@args_nested.rsp +/E + +//--- args_nested.template +/I include +tu.cpp +/FoDIR/tu.obj + +//--- include/header.h + +//--- tu.cpp +#include "header.h" diff --git a/clang/test/CodeCompletion/member-access.cpp b/clang/test/CodeCompletion/member-access.cpp index 9f8c21c0bca6d..912f269db6c1a 100644 --- a/clang/test/CodeCompletion/member-access.cpp +++ b/clang/test/CodeCompletion/member-access.cpp @@ -367,4 +367,20 @@ class A { // CHECK-DEREF-THIS: [#void#]function() } }; + +template +struct RepeatedField { + void Add(); +}; + +template +RepeatedField* MutableRepeatedField() {} + +template +void Foo() { + auto& C = *MutableRepeatedField(); + C. +} +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:382:5 %s -o - | FileCheck -check-prefix=CHECK-DEREF-DEPENDENT %s +// CHECK-DEREF-DEPENDENT: [#void#]Add() } diff --git a/clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c b/clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c index 76c9c0ebed2bb..c678e9a9882f5 100644 --- a/clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c +++ b/clang/test/CodeGen/SystemZ/sync-builtins-i128-8Al.c @@ -7,21 +7,21 @@ __int128 Ptr __attribute__((aligned(8))); __int128 f1() { -// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment] +// CHECK: warning: __sync builtin operation must have natural alignment (consider using __atomic) return __sync_fetch_and_add(&Ptr, 1); } __int128 f2() { -// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment] +// CHECK: warning: __sync builtin operation must have natural alignment (consider using __atomic) return __sync_sub_and_fetch(&Ptr, 1); } __int128 f3() { -// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment] +// CHECK: warning: __sync builtin operation must have natural alignment (consider using __atomic) return __sync_val_compare_and_swap(&Ptr, 0, 1); } void f4() { -// CHECK: warning: __sync builtin operation MUST have natural alignment (consider using __atomic). [-Wsync-alignment] +// CHECK: warning: __sync builtin operation must have natural alignment (consider using __atomic) __sync_lock_release(&Ptr); } diff --git a/clang/test/CodeGen/X86/avx512er-builtins.c b/clang/test/CodeGen/X86/avx512er-builtins.c deleted file mode 100644 index 11ec6aabec1e3..0000000000000 --- a/clang/test/CodeGen/X86/avx512er-builtins.c +++ /dev/null @@ -1,347 +0,0 @@ -// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -target-feature +avx512er -emit-llvm -o - -Wall | FileCheck %s - - -#include - -__m512d test_mm512_rsqrt28_round_pd(__m512d a) { - // CHECK-LABEL: @test_mm512_rsqrt28_round_pd - // CHECK: @llvm.x86.avx512.rsqrt28.pd - return _mm512_rsqrt28_round_pd(a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_mask_rsqrt28_round_pd(__m512d s, __mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_mask_rsqrt28_round_pd - // CHECK: @llvm.x86.avx512.rsqrt28.pd - return _mm512_mask_rsqrt28_round_pd(s, m, a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_maskz_rsqrt28_round_pd(__mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_maskz_rsqrt28_round_pd - // CHECK: @llvm.x86.avx512.rsqrt28.pd - return _mm512_maskz_rsqrt28_round_pd(m, a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_rsqrt28_pd(__m512d a) { - // CHECK-LABEL: @test_mm512_rsqrt28_pd - // CHECK: @llvm.x86.avx512.rsqrt28.pd - return _mm512_rsqrt28_pd(a); -} - -__m512d test_mm512_mask_rsqrt28_pd(__m512d s, __mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_mask_rsqrt28_pd - // CHECK: @llvm.x86.avx512.rsqrt28.pd - return _mm512_mask_rsqrt28_pd(s, m, a); -} - -__m512d test_mm512_maskz_rsqrt28_pd(__mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_maskz_rsqrt28_pd - // CHECK: @llvm.x86.avx512.rsqrt28.pd - return _mm512_maskz_rsqrt28_pd(m, a); -} - -__m512 test_mm512_rsqrt28_round_ps(__m512 a) { - // CHECK-LABEL: @test_mm512_rsqrt28_round_ps - // CHECK: @llvm.x86.avx512.rsqrt28.ps - return _mm512_rsqrt28_round_ps(a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_mask_rsqrt28_round_ps(__m512 s, __mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_mask_rsqrt28_round_ps - // CHECK: @llvm.x86.avx512.rsqrt28.ps - return _mm512_mask_rsqrt28_round_ps(s, m, a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_maskz_rsqrt28_round_ps(__mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_maskz_rsqrt28_round_ps - // CHECK: @llvm.x86.avx512.rsqrt28.ps - return _mm512_maskz_rsqrt28_round_ps(m, a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_rsqrt28_ps(__m512 a) { - // CHECK-LABEL: @test_mm512_rsqrt28_ps - // CHECK: @llvm.x86.avx512.rsqrt28.ps - return _mm512_rsqrt28_ps(a); -} - -__m512 test_mm512_mask_rsqrt28_ps(__m512 s, __mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_mask_rsqrt28_ps - // CHECK: @llvm.x86.avx512.rsqrt28.ps - return _mm512_mask_rsqrt28_ps(s, m, a); -} - -__m512 test_mm512_maskz_rsqrt28_ps(__mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_maskz_rsqrt28_ps - // CHECK: @llvm.x86.avx512.rsqrt28.ps - return _mm512_maskz_rsqrt28_ps(m, a); -} - -__m128 test_mm_rsqrt28_round_ss(__m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_rsqrt28_round_ss - // CHECK: @llvm.x86.avx512.rsqrt28.ss - return _mm_rsqrt28_round_ss(a, b, _MM_FROUND_NO_EXC); -} - -__m128 test_mm_mask_rsqrt28_round_ss(__m128 s, __mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_mask_rsqrt28_round_ss - // CHECK: @llvm.x86.avx512.rsqrt28.ss - return _mm_mask_rsqrt28_round_ss(s, m, a, b, _MM_FROUND_NO_EXC); -} - -__m128 test_mm_maskz_rsqrt28_round_ss(__mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_maskz_rsqrt28_round_ss - // CHECK: @llvm.x86.avx512.rsqrt28.ss - return _mm_maskz_rsqrt28_round_ss(m, a, b, _MM_FROUND_NO_EXC); -} - -__m128 test_mm_rsqrt28_ss(__m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_rsqrt28_ss - // CHECK: @llvm.x86.avx512.rsqrt28.ss - return _mm_rsqrt28_ss(a, b); -} - -__m128 test_mm_mask_rsqrt28_ss(__m128 s, __mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_mask_rsqrt28_ss - // CHECK: @llvm.x86.avx512.rsqrt28.ss - return _mm_mask_rsqrt28_ss(s, m, a, b); -} - -__m128 test_mm_maskz_rsqrt28_ss(__mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_maskz_rsqrt28_ss - // CHECK: @llvm.x86.avx512.rsqrt28.ss - return _mm_maskz_rsqrt28_ss(m, a, b); -} - -__m128d test_mm_rsqrt28_round_sd(__m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_rsqrt28_round_sd - // CHECK: @llvm.x86.avx512.rsqrt28.sd - return _mm_rsqrt28_round_sd(a, b, _MM_FROUND_NO_EXC); -} - -__m128d test_mm_mask_rsqrt28_round_sd(__m128d s, __mmask8 m, __m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_mask_rsqrt28_round_sd - // CHECK: @llvm.x86.avx512.rsqrt28.sd - return _mm_mask_rsqrt28_round_sd(s, m, a, b, _MM_FROUND_NO_EXC); -} - -__m128d test_mm_maskz_rsqrt28_round_sd(__mmask8 m, __m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_maskz_rsqrt28_round_sd - // CHECK: @llvm.x86.avx512.rsqrt28.sd - return _mm_maskz_rsqrt28_round_sd(m, a, b, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_rcp28_round_pd(__m512d a) { - // CHECK-LABEL: @test_mm512_rcp28_round_pd - // CHECK: @llvm.x86.avx512.rcp28.pd - return _mm512_rcp28_round_pd(a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_mask_rcp28_round_pd(__m512d s, __mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_mask_rcp28_round_pd - // CHECK: @llvm.x86.avx512.rcp28.pd - return _mm512_mask_rcp28_round_pd(s, m, a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_maskz_rcp28_round_pd(__mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_maskz_rcp28_round_pd - // CHECK: @llvm.x86.avx512.rcp28.pd - return _mm512_maskz_rcp28_round_pd(m, a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_rcp28_pd(__m512d a) { - // CHECK-LABEL: @test_mm512_rcp28_pd - // CHECK: @llvm.x86.avx512.rcp28.pd - return _mm512_rcp28_pd(a); -} - -__m512d test_mm512_mask_rcp28_pd(__m512d s, __mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_mask_rcp28_pd - // CHECK: @llvm.x86.avx512.rcp28.pd - return _mm512_mask_rcp28_pd(s, m, a); -} - -__m512d test_mm512_maskz_rcp28_pd(__mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_maskz_rcp28_pd - // CHECK: @llvm.x86.avx512.rcp28.pd - return _mm512_maskz_rcp28_pd(m, a); -} - -__m512 test_mm512_rcp28_round_ps(__m512 a) { - // CHECK-LABEL: @test_mm512_rcp28_round_ps - // CHECK: @llvm.x86.avx512.rcp28.ps - return _mm512_rcp28_round_ps(a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_mask_rcp28_round_ps(__m512 s, __mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_mask_rcp28_round_ps - // CHECK: @llvm.x86.avx512.rcp28.ps - return _mm512_mask_rcp28_round_ps(s, m, a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_maskz_rcp28_round_ps(__mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_maskz_rcp28_round_ps - // CHECK: @llvm.x86.avx512.rcp28.ps - return _mm512_maskz_rcp28_round_ps(m, a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_rcp28_ps(__m512 a) { - // CHECK-LABEL: @test_mm512_rcp28_ps - // CHECK: @llvm.x86.avx512.rcp28.ps - return _mm512_rcp28_ps(a); -} - -__m512 test_mm512_mask_rcp28_ps(__m512 s, __mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_mask_rcp28_ps - // CHECK: @llvm.x86.avx512.rcp28.ps - return _mm512_mask_rcp28_ps(s, m, a); -} - -__m512 test_mm512_maskz_rcp28_ps(__mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_maskz_rcp28_ps - // CHECK: @llvm.x86.avx512.rcp28.ps - return _mm512_maskz_rcp28_ps(m, a); -} - -__m128 test_mm_rcp28_round_ss(__m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_rcp28_round_ss - // CHECK: @llvm.x86.avx512.rcp28.ss - return _mm_rcp28_round_ss(a, b, _MM_FROUND_NO_EXC); -} - -__m128 test_mm_mask_rcp28_round_ss(__m128 s, __mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_mask_rcp28_round_ss - // CHECK: @llvm.x86.avx512.rcp28.ss - return _mm_mask_rcp28_round_ss(s, m, a, b, _MM_FROUND_NO_EXC); -} - -__m128 test_mm_maskz_rcp28_round_ss(__mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_maskz_rcp28_round_ss - // CHECK: @llvm.x86.avx512.rcp28.ss - return _mm_maskz_rcp28_round_ss(m, a, b, _MM_FROUND_NO_EXC); -} - -__m128 test_mm_rcp28_ss(__m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_rcp28_ss - // CHECK: @llvm.x86.avx512.rcp28.ss - return _mm_rcp28_ss(a, b); -} - -__m128 test_mm_mask_rcp28_ss(__m128 s, __mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_mask_rcp28_ss - // CHECK: @llvm.x86.avx512.rcp28.ss - return _mm_mask_rcp28_ss(s, m, a, b); -} - -__m128 test_mm_maskz_rcp28_ss(__mmask16 m, __m128 a, __m128 b) { - // CHECK-LABEL: @test_mm_maskz_rcp28_ss - // CHECK: @llvm.x86.avx512.rcp28.ss - return _mm_maskz_rcp28_ss(m, a, b); -} - -__m128d test_mm_rcp28_round_sd(__m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_rcp28_round_sd - // CHECK: @llvm.x86.avx512.rcp28.sd - return _mm_rcp28_round_sd(a, b, _MM_FROUND_NO_EXC); -} - -__m128d test_mm_mask_rcp28_round_sd(__m128d s, __mmask8 m, __m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_mask_rcp28_round_sd - // CHECK: @llvm.x86.avx512.rcp28.sd - return _mm_mask_rcp28_round_sd(s, m, a, b, _MM_FROUND_NO_EXC); -} - -__m128d test_mm_maskz_rcp28_round_sd(__mmask8 m, __m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_maskz_rcp28_round_sd - // CHECK: @llvm.x86.avx512.rcp28.sd - return _mm_maskz_rcp28_round_sd(m, a, b, _MM_FROUND_NO_EXC); -} - -__m128d test_mm_rcp28_sd(__m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_rcp28_sd - // CHECK: @llvm.x86.avx512.rcp28.sd - return _mm_rcp28_sd(a, b); -} - -__m128d test_mm_mask_rcp28_sd(__m128d s, __mmask8 m, __m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_mask_rcp28_sd - // CHECK: @llvm.x86.avx512.rcp28.sd - return _mm_mask_rcp28_sd(s, m, a, b); -} - -__m128d test_mm_maskz_rcp28_sd(__mmask8 m, __m128d a, __m128d b) { - // CHECK-LABEL: @test_mm_maskz_rcp28_sd - // CHECK: @llvm.x86.avx512.rcp28.sd - return _mm_maskz_rcp28_sd(m, a, b); -} - -__m512d test_mm512_exp2a23_round_pd(__m512d a) { - // CHECK-LABEL: @test_mm512_exp2a23_round_pd - // CHECK: @llvm.x86.avx512.exp2.pd - return _mm512_exp2a23_round_pd(a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_mask_exp2a23_round_pd(__m512d s, __mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_mask_exp2a23_round_pd - // CHECK: @llvm.x86.avx512.exp2.pd - return _mm512_mask_exp2a23_round_pd(s, m, a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_maskz_exp2a23_round_pd(__mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_maskz_exp2a23_round_pd - // CHECK: @llvm.x86.avx512.exp2.pd - return _mm512_maskz_exp2a23_round_pd(m, a, _MM_FROUND_NO_EXC); -} - -__m512d test_mm512_exp2a23_pd(__m512d a) { - // CHECK-LABEL: @test_mm512_exp2a23_pd - // CHECK: @llvm.x86.avx512.exp2.pd - return _mm512_exp2a23_pd(a); -} - -__m512d test_mm512_mask_exp2a23_pd(__m512d s, __mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_mask_exp2a23_pd - // CHECK: @llvm.x86.avx512.exp2.pd - return _mm512_mask_exp2a23_pd(s, m, a); -} - -__m512d test_mm512_maskz_exp2a23_pd(__mmask8 m, __m512d a) { - // CHECK-LABEL: @test_mm512_maskz_exp2a23_pd - // CHECK: @llvm.x86.avx512.exp2.pd - return _mm512_maskz_exp2a23_pd(m, a); -} - -__m512 test_mm512_exp2a23_round_ps(__m512 a) { - // CHECK-LABEL: @test_mm512_exp2a23_round_ps - // CHECK: @llvm.x86.avx512.exp2.ps - return _mm512_exp2a23_round_ps(a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_mask_exp2a23_round_ps(__m512 s, __mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_mask_exp2a23_round_ps - // CHECK: @llvm.x86.avx512.exp2.ps - return _mm512_mask_exp2a23_round_ps(s, m, a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_maskz_exp2a23_round_ps(__mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_maskz_exp2a23_round_ps - // CHECK: @llvm.x86.avx512.exp2.ps - return _mm512_maskz_exp2a23_round_ps(m, a, _MM_FROUND_NO_EXC); -} - -__m512 test_mm512_exp2a23_ps(__m512 a) { - // CHECK-LABEL: @test_mm512_exp2a23_ps - // CHECK: @llvm.x86.avx512.exp2.ps - return _mm512_exp2a23_ps(a); -} - -__m512 test_mm512_mask_exp2a23_ps(__m512 s, __mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_mask_exp2a23_ps - // CHECK: @llvm.x86.avx512.exp2.ps - return _mm512_mask_exp2a23_ps(s, m, a); -} - -__m512 test_mm512_maskz_exp2a23_ps(__mmask16 m, __m512 a) { - // CHECK-LABEL: @test_mm512_maskz_exp2a23_ps - // CHECK: @llvm.x86.avx512.exp2.ps - return _mm512_maskz_exp2a23_ps(m, a); -} - diff --git a/clang/test/CodeGen/X86/avx512pf-builtins.c b/clang/test/CodeGen/X86/avx512pf-builtins.c deleted file mode 100644 index 3a117ed6a9460..0000000000000 --- a/clang/test/CodeGen/X86/avx512pf-builtins.c +++ /dev/null @@ -1,100 +0,0 @@ -// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512pf -emit-llvm -o - -Wall | FileCheck %s - - -#include - -void test_mm512_mask_prefetch_i32gather_pd(__m256i index, __mmask8 mask, void const *addr) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i32gather_pd - // CHECK: @llvm.x86.avx512.gatherpf.dpd - return _mm512_mask_prefetch_i32gather_pd(index, mask, addr, 2, _MM_HINT_T0); -} - -void test_mm512_prefetch_i32gather_pd(__m256i index, void const *addr) { - // CHECK-LABEL: @test_mm512_prefetch_i32gather_pd - // CHECK: @llvm.x86.avx512.gatherpf.dpd - return _mm512_prefetch_i32gather_pd(index, addr, 2, _MM_HINT_T0); -} - -void test_mm512_mask_prefetch_i32gather_ps(__m512i index, __mmask16 mask, void const *addr) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i32gather_ps - // CHECK: @llvm.x86.avx512.gatherpf.dps - return _mm512_mask_prefetch_i32gather_ps(index, mask, addr, 2, _MM_HINT_T0); -} - -void test_mm512_prefetch_i32gather_ps(__m512i index, void const *addr) { - // CHECK-LABEL: @test_mm512_prefetch_i32gather_ps - // CHECK: @llvm.x86.avx512.gatherpf.dps - return _mm512_prefetch_i32gather_ps(index, addr, 2, _MM_HINT_T0); -} - -void test_mm512_mask_prefetch_i64gather_pd(__m512i index, __mmask8 mask, void const *addr) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i64gather_pd - // CHECK: @llvm.x86.avx512.gatherpf.qpd - return _mm512_mask_prefetch_i64gather_pd(index, mask, addr, 2, _MM_HINT_T0); -} - -void test_mm512_prefetch_i64gather_pd(__m512i index, void const *addr) { - // CHECK-LABEL: @test_mm512_prefetch_i64gather_pd - // CHECK: @llvm.x86.avx512.gatherpf.qpd - return _mm512_prefetch_i64gather_pd(index, addr, 2, _MM_HINT_T0); -} - -void test_mm512_mask_prefetch_i64gather_ps(__m512i index, __mmask8 mask, void const *addr) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i64gather_ps - // CHECK: @llvm.x86.avx512.gatherpf.qps - return _mm512_mask_prefetch_i64gather_ps(index, mask, addr, 2, _MM_HINT_T0); -} - -void test_mm512_prefetch_i64gather_ps(__m512i index, void const *addr) { - // CHECK-LABEL: @test_mm512_prefetch_i64gather_ps - // CHECK: @llvm.x86.avx512.gatherpf.qps - return _mm512_prefetch_i64gather_ps(index, addr, 2, _MM_HINT_T0); -} - -void test_mm512_prefetch_i32scatter_pd(void *addr, __m256i index) { - // CHECK-LABEL: @test_mm512_prefetch_i32scatter_pd - // CHECK: @llvm.x86.avx512.scatterpf.dpd.512 - return _mm512_prefetch_i32scatter_pd(addr, index, 1, _MM_HINT_T1); -} - -void test_mm512_mask_prefetch_i32scatter_pd(void *addr, __mmask8 mask, __m256i index) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i32scatter_pd - // CHECK: @llvm.x86.avx512.scatterpf.dpd.512 - return _mm512_mask_prefetch_i32scatter_pd(addr, mask, index, 1, _MM_HINT_T1); -} - -void test_mm512_prefetch_i32scatter_ps(void *addr, __m512i index) { - // CHECK-LABEL: @test_mm512_prefetch_i32scatter_ps - // CHECK: @llvm.x86.avx512.scatterpf.dps.512 - return _mm512_prefetch_i32scatter_ps(addr, index, 1, _MM_HINT_T1); -} - -void test_mm512_mask_prefetch_i32scatter_ps(void *addr, __mmask16 mask, __m512i index) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i32scatter_ps - // CHECK: @llvm.x86.avx512.scatterpf.dps.512 - return _mm512_mask_prefetch_i32scatter_ps(addr, mask, index, 1, _MM_HINT_T1); -} - -void test_mm512_prefetch_i64scatter_pd(void *addr, __m512i index) { - // CHECK-LABEL: @test_mm512_prefetch_i64scatter_pd - // CHECK: @llvm.x86.avx512.scatterpf.qpd.512 - return _mm512_prefetch_i64scatter_pd(addr, index, 1, _MM_HINT_T1); -} - -void test_mm512_mask_prefetch_i64scatter_pd(void *addr, __mmask16 mask, __m512i index) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i64scatter_pd - // CHECK: @llvm.x86.avx512.scatterpf.qpd.512 - return _mm512_mask_prefetch_i64scatter_pd(addr, mask, index, 1, _MM_HINT_T1); -} - -void test_mm512_prefetch_i64scatter_ps(void *addr, __m512i index) { - // CHECK-LABEL: @test_mm512_prefetch_i64scatter_ps - // CHECK: @llvm.x86.avx512.scatterpf.qps.512 - return _mm512_prefetch_i64scatter_ps(addr, index, 1, _MM_HINT_T1); -} - -void test_mm512_mask_prefetch_i64scatter_ps(void *addr, __mmask16 mask, __m512i index) { - // CHECK-LABEL: @test_mm512_mask_prefetch_i64scatter_ps - // CHECK: @llvm.x86.avx512.scatterpf.qps.512 - return _mm512_mask_prefetch_i64scatter_ps(addr, mask, index, 1, _MM_HINT_T1); -} diff --git a/clang/test/CodeGen/aarch64-byval-temp.c b/clang/test/CodeGen/aarch64-byval-temp.c index e9e2586406e5c..0384830c69a41 100644 --- a/clang/test/CodeGen/aarch64-byval-temp.c +++ b/clang/test/CodeGen/aarch64-byval-temp.c @@ -1,13 +1,14 @@ -// RUN: %clang_cc1 -emit-llvm -triple arm64-- -o - %s -O0 | FileCheck %s --check-prefix=CHECK-O0 -// RUN: %clang_cc1 -emit-llvm -disable-llvm-optzns -triple arm64-- -o - %s -O3 | FileCheck %s --check-prefix=CHECK-O3 +// RUN: %clang_cc1 -emit-llvm -triple arm64-- -fexperimental-max-bitint-width=1024 -o - %s -O0 | FileCheck %s --check-prefix=CHECK-O0 +// RUN: %clang_cc1 -emit-llvm -disable-llvm-optzns -fexperimental-max-bitint-width=1024 -triple arm64-- -o - %s -O3 | FileCheck %s --check-prefix=CHECK-O3 struct large { void* pointers[8]; }; void pass_large(struct large); +void pass_large_BitInt(_BitInt(129)); -// For arm64, we don't use byval to pass structs but instead we create +// For arm64, we don't use byval to pass structs and _BitInt(>128) type, but instead we create // temporary allocas. // // Make sure we generate the appropriate lifetime markers for the temporary @@ -71,3 +72,41 @@ void example(void) { // Mark the end of the lifetime of `l`. // CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr %l) // CHECK-O3-NEXT: ret void + +void example_BitInt(void) { + _BitInt(129) l = {0}; + pass_large_BitInt(l); + pass_large_BitInt(l); +} +// CHECK-O0-LABEL: define dso_local void @example_BitInt( +// CHECK-O0-NEXT: entry: +// CHECK-O0-NEXT: [[L:%.*]] = alloca i129, align 16 +// CHECK-O0-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i129, align 16 +// CHECK-O0-NEXT: [[INDIRECT_ARG_TEMP1:%.*]] = alloca i129, align 16 +// CHECK-O0-NEXT: store i129 0, ptr [[L]], align 16 +// CHECK-O0-NEXT: [[TMP0:%.*]] = load i129, ptr [[L]], align 16 +// CHECK-O0-NEXT: store i129 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 16 +// CHECK-O0-NEXT: call void @pass_large_BitInt(ptr noundef [[INDIRECT_ARG_TEMP]]) +// CHECK-O0-NEXT: [[TMP1:%.*]] = load i129, ptr [[L]], align 16 +// CHECK-O0-NEXT: store i129 [[TMP1]], ptr [[INDIRECT_ARG_TEMP1]], align 16 +// CHECK-O0-NEXT: call void @pass_large_BitInt(ptr noundef [[INDIRECT_ARG_TEMP1]]) +// CHECK-O0-NEXT: ret void +// +// CHECK-O3-LABEL: define dso_local void @example_BitInt( +// CHECK-O3-NEXT: entry: +// CHECK-O3-NEXT: [[L:%.*]] = alloca i129, align 16 +// CHECK-O3-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i129, align 16 +// CHECK-O3-NEXT: [[INDIRECT_ARG_TEMP1:%.*]] = alloca i129, align 16 +// CHECK-O3-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[L]]) +// CHECK-O3-NEXT: store i129 0, ptr [[L]], align 16, !tbaa [[TBAA6:![0-9]+]] +// CHECK-O3-NEXT: [[TMP0:%.*]] = load i129, ptr [[L]], align 16, !tbaa [[TBAA6]] +// CHECK-O3-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[INDIRECT_ARG_TEMP]]) +// CHECK-O3-NEXT: store i129 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 16, !tbaa [[TBAA6]] +// CHECK-O3-NEXT: call void @pass_large_BitInt(ptr noundef [[INDIRECT_ARG_TEMP]]) +// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr [[INDIRECT_ARG_TEMP]]) +// CHECK-O3-NEXT: [[TMP1:%.*]] = load i129, ptr [[L]], align 16, !tbaa [[TBAA6]] +// CHECK-O3-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[INDIRECT_ARG_TEMP1]]) +// CHECK-O3-NEXT: store i129 [[TMP1]], ptr [[INDIRECT_ARG_TEMP1]], align 16, !tbaa [[TBAA6]] +// CHECK-O3-NEXT: call void @pass_large_BitInt(ptr noundef [[INDIRECT_ARG_TEMP1]]) +// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr [[INDIRECT_ARG_TEMP1]]) +// CHECK-O3-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr [[L]]) diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_reinterpret_svcount_svbool.c b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_reinterpret_svcount_svbool.c index c442d2c0c4750..d894e98451b41 100644 --- a/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_reinterpret_svcount_svbool.c +++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_reinterpret_svcount_svbool.c @@ -2,12 +2,14 @@ // REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64 -target-feature +sve2p1 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +sve2p1 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s // RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK -#include +#include #if defined __ARM_FEATURE_SME #define MODE_ATTR __arm_streaming @@ -16,7 +18,7 @@ #endif #ifdef SVE_OVERLOADED_FORMS -// A simple used,unused... macro, long enough to represent any SVE builtin.§ +// A simple used,unused... macro, long enough to represent any SVE builtin. #define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 #else #define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 diff --git a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c index a4abe96cc08a6..55e1ed393d848 100644 --- a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c +++ b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c @@ -88,8 +88,10 @@ typedef svint8_t vec2 __attribute__((arm_sve_vector_bits(N))); // CHECK-NEXT: entry: // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca <[[#div(VBITS,8)]] x i8>, align 16 // CHECK-NEXT: [[X:%.*]] = tail call <[[#div(VBITS,8)]] x i8> @llvm.vector.extract.v[[#div(VBITS,8)]]i8.nxv16i8( [[X_COERCE:%.*]], i64 0) +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 [[SIZE:[0-9]+]], ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]] // CHECK-NEXT: store <[[#div(VBITS,8)]] x i8> [[X]], ptr [[INDIRECT_ARG_TEMP]], align 16, [[TBAA6]] // CHECK-NEXT: call void @f3(ptr noundef nonnull [[INDIRECT_ARG_TEMP]]) [[ATTR5:#.*]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[SIZE]], ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]] // CHECK-NEXT: ret void // CHECK128-LABEL: declare void @f3(<16 x i8> noundef) diff --git a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp index 05587fd9e7fe2..30ea73b63bce1 100644 --- a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp +++ b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp @@ -73,8 +73,10 @@ typedef svint16_t vec2 __attribute__((arm_sve_vector_bits(N))); // CHECK128-NEXT: ret void // CHECKWIDE-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca <[[#div(VBITS, 16)]] x i16>, align 16 // CHECKWIDE-NEXT: [[X:%.*]] = tail call <[[#div(VBITS, 16)]] x i16> @llvm.vector.extract.v[[#div(VBITS, 16)]]i16.nxv8i16( [[X_COERCE:%.*]], i64 0) +// CHECKWIDE-NEXT: call void @llvm.lifetime.start.p0(i64 [[SIZE:[0-9]+]], ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]] // CHECKWIDE-NEXT: store <[[#div(VBITS, 16)]] x i16> [[X]], ptr [[INDIRECT_ARG_TEMP]], align 16, [[TBAA6:!tbaa !.*]] // CHECKWIDE-NEXT: call void @_Z1fDv[[#div(VBITS, 16)]]_s(ptr noundef nonnull [[INDIRECT_ARG_TEMP]]) [[ATTR5:#.*]] +// CHECKWIDE-NEXT: call void @llvm.lifetime.end.p0(i64 [[SIZE]], ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR6:[0-9]+]] // CHECKWIDE-NEXT: ret void void g(vec2 x) { f(x); } // OK #endif diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c index bf2cd23e40802..41208bfb1f435 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c @@ -4,6 +4,10 @@ // RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x2 -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE2 // RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x3 -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE3 // RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x4 -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE4 +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x2 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE2 +// RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x3 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE3 +// RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x4 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE4 // RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x2 -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE2 // RUN: %clang_cc1 -fclang-abi-compat=latest -DTUPLE=x3 -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE3 @@ -18,9 +22,16 @@ // RUN: %clang_cc1 -fclang-abi-compat=latest -DSVE_OVERLOADED_FORMS -DTUPLE=x4 -triple aarch64 -target-feature +sve -target-feature +bf16 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE4 // RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature +sve -target-feature +bf16 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -fclang-abi-compat=latest -triple aarch64 -target-feature +sme -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include +#if defined __ARM_FEATURE_SME +#define MODE_ATTR __arm_streaming +#else +#define MODE_ATTR +#endif + #ifdef TUPLE #define TYPE_1(base,tuple) base ## tuple ## _t #define TYPE_0(base,tuple) TYPE_1(base,tuple) @@ -81,7 +92,7 @@ // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_bf16(TYPE(svbfloat16) op) { +TYPE(svint8) test_svreinterpret_s8_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8, _bf16)(op); } @@ -125,7 +136,7 @@ TYPE(svint8) test_svreinterpret_s8_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_bf16(TYPE(svbfloat16) op) { +TYPE(svint16) test_svreinterpret_s16_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16, _bf16)(op); } @@ -169,7 +180,7 @@ TYPE(svint16) test_svreinterpret_s16_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_bf16(TYPE(svbfloat16) op) { +TYPE(svint32) test_svreinterpret_s32_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32, _bf16)(op); } // CHECK-LABEL: @test_svreinterpret_s64_bf16( @@ -212,7 +223,7 @@ TYPE(svint32) test_svreinterpret_s32_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_bf16(TYPE(svbfloat16) op) { +TYPE(svint64) test_svreinterpret_s64_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64, _bf16)(op); } @@ -256,7 +267,7 @@ TYPE(svint64) test_svreinterpret_s64_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_bf16(TYPE(svbfloat16) op) { +TYPE(svuint8) test_svreinterpret_u8_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8, _bf16)(op); } @@ -300,7 +311,7 @@ TYPE(svuint8) test_svreinterpret_u8_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_bf16(TYPE(svbfloat16) op) { +TYPE(svuint16) test_svreinterpret_u16_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16, _bf16)(op); } @@ -344,7 +355,7 @@ TYPE(svuint16) test_svreinterpret_u16_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_bf16(TYPE(svbfloat16) op) { +TYPE(svuint32) test_svreinterpret_u32_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32, _bf16)(op); } @@ -388,7 +399,7 @@ TYPE(svuint32) test_svreinterpret_u32_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_bf16(TYPE(svbfloat16) op) { +TYPE(svuint64) test_svreinterpret_u64_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64, _bf16)(op); } @@ -432,7 +443,7 @@ TYPE(svuint64) test_svreinterpret_u64_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_s8(TYPE(svint8) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _s8)(op); } @@ -476,7 +487,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_s8(TYPE(svint8) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_s16(TYPE(svint16) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _s16)(op); } @@ -520,7 +531,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_s16(TYPE(svint16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_s32(TYPE(svint32) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _s32)(op); } @@ -564,7 +575,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_s32(TYPE(svint32) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_s64(TYPE(svint64) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _s64)(op); } @@ -608,7 +619,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_s64(TYPE(svint64) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_u8(TYPE(svuint8) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _u8)(op); } @@ -652,7 +663,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_u8(TYPE(svuint8) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_u16(TYPE(svuint16) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _u16)(op); } @@ -696,7 +707,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_u16(TYPE(svuint16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_u32(TYPE(svuint32) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _u32)(op); } @@ -740,7 +751,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_u32(TYPE(svuint32) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_u64(TYPE(svuint64) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _u64)(op); } @@ -776,7 +787,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_u64(TYPE(svuint64) op) { // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svbfloat16) test_svreinterpret_bf16_bf16(TYPE(svbfloat16) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _bf16)(op); } @@ -820,7 +831,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_f16(TYPE(svfloat16) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _f16)(op); } @@ -864,7 +875,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_f16(TYPE(svfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_f32(TYPE(svfloat32) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _f32)(op); } @@ -908,7 +919,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_f32(TYPE(svfloat32) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svbfloat16) test_svreinterpret_bf16_f64(TYPE(svfloat64) op) { +TYPE(svbfloat16) test_svreinterpret_bf16_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_bf16, _f64)(op); } @@ -952,7 +963,7 @@ TYPE(svbfloat16) test_svreinterpret_bf16_f64(TYPE(svfloat64) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_bf16(TYPE(svbfloat16) op) { +TYPE(svfloat32) test_svreinterpret_f32_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32, _bf16)(op); } @@ -996,7 +1007,7 @@ TYPE(svfloat32) test_svreinterpret_f32_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_bf16(TYPE(svbfloat16) op) { +TYPE(svfloat16) test_svreinterpret_f16_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16, _bf16)(op); } @@ -1040,6 +1051,6 @@ TYPE(svfloat16) test_svreinterpret_f16_bf16(TYPE(svbfloat16) op) { // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_bf16(TYPE(svbfloat16) op) { +TYPE(svfloat64) test_svreinterpret_f64_bf16(TYPE(svbfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64, _bf16)(op); } diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c index 3d9d5c3ce45ae..e61bbf3e03d7e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c @@ -4,6 +4,10 @@ // RUN: %clang_cc1 -DTUPLE=x2 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE2 // RUN: %clang_cc1 -DTUPLE=x3 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE3 // RUN: %clang_cc1 -DTUPLE=x4 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE4 +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DTUPLE=x2 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE2 +// RUN: %clang_cc1 -DTUPLE=x3 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE3 +// RUN: %clang_cc1 -DTUPLE=x4 -triple aarch64 -target-feature +sme -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=TUPLE4 // RUN: %clang_cc1 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK // RUN: %clang_cc1 -DTUPLE=x2 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE2 // RUN: %clang_cc1 -DTUPLE=x3 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE3 @@ -17,9 +21,16 @@ // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -DTUPLE=x3 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE3 // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -DTUPLE=x4 -triple aarch64 -target-feature +sve -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-TUPLE4 // RUN: %clang_cc1 -triple aarch64 -target-feature +sve -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -S -disable-O0-optnone -Werror -Wall -o /dev/null %s #include +#if defined __ARM_FEATURE_SME +#define MODE_ATTR __arm_streaming +#else +#define MODE_ATTR +#endif + #ifdef TUPLE #define TYPE_1(base,tuple) base ## tuple ## _t #define TYPE_0(base,tuple) TYPE_1(base,tuple) @@ -72,7 +83,7 @@ // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint8) test_svreinterpret_s8_s8(TYPE(svint8) op) +TYPE(svint8) test_svreinterpret_s8_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_s8)(op); } @@ -117,7 +128,7 @@ TYPE(svint8) test_svreinterpret_s8_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_s16(TYPE(svint16) op) +TYPE(svint8) test_svreinterpret_s8_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_s16)(op); } @@ -162,7 +173,7 @@ TYPE(svint8) test_svreinterpret_s8_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_s32(TYPE(svint32) op) +TYPE(svint8) test_svreinterpret_s8_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_s32)(op); } @@ -207,7 +218,7 @@ TYPE(svint8) test_svreinterpret_s8_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_s64(TYPE(svint64) op) +TYPE(svint8) test_svreinterpret_s8_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_s64)(op); } @@ -244,7 +255,7 @@ TYPE(svint8) test_svreinterpret_s8_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint8) test_svreinterpret_s8_u8(TYPE(svuint8) op) +TYPE(svint8) test_svreinterpret_s8_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_u8)(op); } @@ -289,7 +300,7 @@ TYPE(svint8) test_svreinterpret_s8_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_u16(TYPE(svuint16) op) +TYPE(svint8) test_svreinterpret_s8_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_u16)(op); } @@ -335,7 +346,7 @@ TYPE(svint8) test_svreinterpret_s8_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_u32(TYPE(svuint32) op) +TYPE(svint8) test_svreinterpret_s8_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_u32)(op); } @@ -381,7 +392,7 @@ TYPE(svint8) test_svreinterpret_s8_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_u64(TYPE(svuint64) op) +TYPE(svint8) test_svreinterpret_s8_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_u64)(op); } @@ -426,7 +437,7 @@ TYPE(svint8) test_svreinterpret_s8_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_f16(TYPE(svfloat16) op) +TYPE(svint8) test_svreinterpret_s8_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_f16)(op); } @@ -471,7 +482,7 @@ TYPE(svint8) test_svreinterpret_s8_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_f32(TYPE(svfloat32) op) +TYPE(svint8) test_svreinterpret_s8_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_f32)(op); } @@ -516,7 +527,7 @@ TYPE(svint8) test_svreinterpret_s8_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint8) test_svreinterpret_s8_f64(TYPE(svfloat64) op) +TYPE(svint8) test_svreinterpret_s8_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s8,_f64)(op); } @@ -561,7 +572,7 @@ TYPE(svint8) test_svreinterpret_s8_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_s8(TYPE(svint8) op) +TYPE(svint16) test_svreinterpret_s16_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_s8)(op); } @@ -598,7 +609,7 @@ TYPE(svint16) test_svreinterpret_s16_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint16) test_svreinterpret_s16_s16(TYPE(svint16) op) +TYPE(svint16) test_svreinterpret_s16_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_s16)(op); } @@ -643,7 +654,7 @@ TYPE(svint16) test_svreinterpret_s16_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_s32(TYPE(svint32) op) +TYPE(svint16) test_svreinterpret_s16_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_s32)(op); } @@ -688,7 +699,7 @@ TYPE(svint16) test_svreinterpret_s16_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_s64(TYPE(svint64) op) +TYPE(svint16) test_svreinterpret_s16_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_s64)(op); } @@ -733,7 +744,7 @@ TYPE(svint16) test_svreinterpret_s16_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_u8(TYPE(svuint8) op) +TYPE(svint16) test_svreinterpret_s16_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_u8)(op); } @@ -770,7 +781,7 @@ TYPE(svint16) test_svreinterpret_s16_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint16) test_svreinterpret_s16_u16(TYPE(svuint16) op) +TYPE(svint16) test_svreinterpret_s16_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_u16)(op); } @@ -815,7 +826,7 @@ TYPE(svint16) test_svreinterpret_s16_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_u32(TYPE(svuint32) op) +TYPE(svint16) test_svreinterpret_s16_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_u32)(op); } @@ -860,7 +871,7 @@ TYPE(svint16) test_svreinterpret_s16_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_u64(TYPE(svuint64) op) +TYPE(svint16) test_svreinterpret_s16_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_u64)(op); } @@ -905,7 +916,7 @@ TYPE(svint16) test_svreinterpret_s16_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_f16(TYPE(svfloat16) op) +TYPE(svint16) test_svreinterpret_s16_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_f16)(op); } @@ -950,7 +961,7 @@ TYPE(svint16) test_svreinterpret_s16_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_f32(TYPE(svfloat32) op) +TYPE(svint16) test_svreinterpret_s16_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_f32)(op); } @@ -995,7 +1006,7 @@ TYPE(svint16) test_svreinterpret_s16_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint16) test_svreinterpret_s16_f64(TYPE(svfloat64) op) +TYPE(svint16) test_svreinterpret_s16_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s16,_f64)(op); } @@ -1040,7 +1051,7 @@ TYPE(svint16) test_svreinterpret_s16_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_s8(TYPE(svint8) op) +TYPE(svint32) test_svreinterpret_s32_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_s8)(op); } @@ -1085,7 +1096,7 @@ TYPE(svint32) test_svreinterpret_s32_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_s16(TYPE(svint16) op) +TYPE(svint32) test_svreinterpret_s32_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_s16)(op); } @@ -1122,7 +1133,7 @@ TYPE(svint32) test_svreinterpret_s32_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint32) test_svreinterpret_s32_s32(TYPE(svint32) op) +TYPE(svint32) test_svreinterpret_s32_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_s32)(op); } @@ -1167,7 +1178,7 @@ TYPE(svint32) test_svreinterpret_s32_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_s64(TYPE(svint64) op) +TYPE(svint32) test_svreinterpret_s32_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_s64)(op); } @@ -1212,7 +1223,7 @@ TYPE(svint32) test_svreinterpret_s32_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_u8(TYPE(svuint8) op) +TYPE(svint32) test_svreinterpret_s32_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_u8)(op); } @@ -1257,7 +1268,7 @@ TYPE(svint32) test_svreinterpret_s32_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_u16(TYPE(svuint16) op) +TYPE(svint32) test_svreinterpret_s32_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_u16)(op); } @@ -1294,7 +1305,7 @@ TYPE(svint32) test_svreinterpret_s32_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint32) test_svreinterpret_s32_u32(TYPE(svuint32) op) +TYPE(svint32) test_svreinterpret_s32_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_u32)(op); } @@ -1339,7 +1350,7 @@ TYPE(svint32) test_svreinterpret_s32_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_u64(TYPE(svuint64) op) +TYPE(svint32) test_svreinterpret_s32_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_u64)(op); } @@ -1384,7 +1395,7 @@ TYPE(svint32) test_svreinterpret_s32_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_f16(TYPE(svfloat16) op) +TYPE(svint32) test_svreinterpret_s32_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_f16)(op); } @@ -1429,7 +1440,7 @@ TYPE(svint32) test_svreinterpret_s32_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_f32(TYPE(svfloat32) op) +TYPE(svint32) test_svreinterpret_s32_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_f32)(op); } @@ -1475,7 +1486,7 @@ TYPE(svint32) test_svreinterpret_s32_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint32) test_svreinterpret_s32_f64(TYPE(svfloat64) op) +TYPE(svint32) test_svreinterpret_s32_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s32,_f64)(op); } @@ -1520,7 +1531,7 @@ TYPE(svint32) test_svreinterpret_s32_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_s8(TYPE(svint8) op) +TYPE(svint64) test_svreinterpret_s64_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_s8)(op); } @@ -1565,7 +1576,7 @@ TYPE(svint64) test_svreinterpret_s64_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_s16(TYPE(svint16) op) +TYPE(svint64) test_svreinterpret_s64_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_s16)(op); } @@ -1610,7 +1621,7 @@ TYPE(svint64) test_svreinterpret_s64_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_s32(TYPE(svint32) op) +TYPE(svint64) test_svreinterpret_s64_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_s32)(op); } @@ -1647,7 +1658,7 @@ TYPE(svint64) test_svreinterpret_s64_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint64) test_svreinterpret_s64_s64(TYPE(svint64) op) +TYPE(svint64) test_svreinterpret_s64_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_s64)(op); } @@ -1692,7 +1703,7 @@ TYPE(svint64) test_svreinterpret_s64_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_u8(TYPE(svuint8) op) +TYPE(svint64) test_svreinterpret_s64_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_u8)(op); } @@ -1737,7 +1748,7 @@ TYPE(svint64) test_svreinterpret_s64_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_u16(TYPE(svuint16) op) +TYPE(svint64) test_svreinterpret_s64_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_u16)(op); } @@ -1782,7 +1793,7 @@ TYPE(svint64) test_svreinterpret_s64_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_u32(TYPE(svuint32) op) +TYPE(svint64) test_svreinterpret_s64_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_u32)(op); } @@ -1819,7 +1830,7 @@ TYPE(svint64) test_svreinterpret_s64_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svint64) test_svreinterpret_s64_u64(TYPE(svuint64) op) +TYPE(svint64) test_svreinterpret_s64_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_u64)(op); } @@ -1864,7 +1875,7 @@ TYPE(svint64) test_svreinterpret_s64_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_f16(TYPE(svfloat16) op) +TYPE(svint64) test_svreinterpret_s64_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_f16)(op); } @@ -1909,7 +1920,7 @@ TYPE(svint64) test_svreinterpret_s64_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_f32(TYPE(svfloat32) op) +TYPE(svint64) test_svreinterpret_s64_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_f32)(op); } @@ -1954,7 +1965,7 @@ TYPE(svint64) test_svreinterpret_s64_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svint64) test_svreinterpret_s64_f64(TYPE(svfloat64) op) +TYPE(svint64) test_svreinterpret_s64_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_s64,_f64)(op); } @@ -1991,7 +2002,7 @@ TYPE(svint64) test_svreinterpret_s64_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint8) test_svreinterpret_u8_s8(TYPE(svint8) op) +TYPE(svuint8) test_svreinterpret_u8_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_s8)(op); } @@ -2036,7 +2047,7 @@ TYPE(svuint8) test_svreinterpret_u8_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_s16(TYPE(svint16) op) +TYPE(svuint8) test_svreinterpret_u8_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_s16)(op); } @@ -2081,7 +2092,7 @@ TYPE(svuint8) test_svreinterpret_u8_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_s32(TYPE(svint32) op) +TYPE(svuint8) test_svreinterpret_u8_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_s32)(op); } @@ -2126,7 +2137,7 @@ TYPE(svuint8) test_svreinterpret_u8_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_s64(TYPE(svint64) op) +TYPE(svuint8) test_svreinterpret_u8_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_s64)(op); } @@ -2163,7 +2174,7 @@ TYPE(svuint8) test_svreinterpret_u8_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint8) test_svreinterpret_u8_u8(TYPE(svuint8) op) +TYPE(svuint8) test_svreinterpret_u8_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_u8)(op); } @@ -2208,7 +2219,7 @@ TYPE(svuint8) test_svreinterpret_u8_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_u16(TYPE(svuint16) op) +TYPE(svuint8) test_svreinterpret_u8_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_u16)(op); } @@ -2253,7 +2264,7 @@ TYPE(svuint8) test_svreinterpret_u8_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_u32(TYPE(svuint32) op) +TYPE(svuint8) test_svreinterpret_u8_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_u32)(op); } @@ -2298,7 +2309,7 @@ TYPE(svuint8) test_svreinterpret_u8_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_u64(TYPE(svuint64) op) +TYPE(svuint8) test_svreinterpret_u8_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_u64)(op); } @@ -2343,7 +2354,7 @@ TYPE(svuint8) test_svreinterpret_u8_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_f16(TYPE(svfloat16) op) +TYPE(svuint8) test_svreinterpret_u8_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_f16)(op); } @@ -2388,7 +2399,7 @@ TYPE(svuint8) test_svreinterpret_u8_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_f32(TYPE(svfloat32) op) +TYPE(svuint8) test_svreinterpret_u8_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_f32)(op); } @@ -2433,7 +2444,7 @@ TYPE(svuint8) test_svreinterpret_u8_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint8) test_svreinterpret_u8_f64(TYPE(svfloat64) op) +TYPE(svuint8) test_svreinterpret_u8_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u8,_f64)(op); } @@ -2478,7 +2489,7 @@ TYPE(svuint8) test_svreinterpret_u8_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_s8(TYPE(svint8) op) +TYPE(svuint16) test_svreinterpret_u16_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_s8)(op); } @@ -2515,7 +2526,7 @@ TYPE(svuint16) test_svreinterpret_u16_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint16) test_svreinterpret_u16_s16(TYPE(svint16) op) +TYPE(svuint16) test_svreinterpret_u16_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_s16)(op); } @@ -2560,7 +2571,7 @@ TYPE(svuint16) test_svreinterpret_u16_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_s32(TYPE(svint32) op) +TYPE(svuint16) test_svreinterpret_u16_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_s32)(op); } @@ -2605,7 +2616,7 @@ TYPE(svuint16) test_svreinterpret_u16_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_s64(TYPE(svint64) op) +TYPE(svuint16) test_svreinterpret_u16_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_s64)(op); } @@ -2650,7 +2661,7 @@ TYPE(svuint16) test_svreinterpret_u16_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_u8(TYPE(svuint8) op) +TYPE(svuint16) test_svreinterpret_u16_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_u8)(op); } @@ -2687,7 +2698,7 @@ TYPE(svuint16) test_svreinterpret_u16_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint16) test_svreinterpret_u16_u16(TYPE(svuint16) op) +TYPE(svuint16) test_svreinterpret_u16_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_u16)(op); } @@ -2732,7 +2743,7 @@ TYPE(svuint16) test_svreinterpret_u16_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_u32(TYPE(svuint32) op) +TYPE(svuint16) test_svreinterpret_u16_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_u32)(op); } @@ -2777,7 +2788,7 @@ TYPE(svuint16) test_svreinterpret_u16_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_u64(TYPE(svuint64) op) +TYPE(svuint16) test_svreinterpret_u16_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_u64)(op); } @@ -2822,7 +2833,7 @@ TYPE(svuint16) test_svreinterpret_u16_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_f16(TYPE(svfloat16) op) +TYPE(svuint16) test_svreinterpret_u16_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_f16)(op); } @@ -2867,7 +2878,7 @@ TYPE(svuint16) test_svreinterpret_u16_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_f32(TYPE(svfloat32) op) +TYPE(svuint16) test_svreinterpret_u16_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_f32)(op); } @@ -2912,7 +2923,7 @@ TYPE(svuint16) test_svreinterpret_u16_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint16) test_svreinterpret_u16_f64(TYPE(svfloat64) op) +TYPE(svuint16) test_svreinterpret_u16_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u16,_f64)(op); } @@ -2957,7 +2968,7 @@ TYPE(svuint16) test_svreinterpret_u16_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_s8(TYPE(svint8) op) +TYPE(svuint32) test_svreinterpret_u32_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_s8)(op); } @@ -3002,7 +3013,7 @@ TYPE(svuint32) test_svreinterpret_u32_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_s16(TYPE(svint16) op) +TYPE(svuint32) test_svreinterpret_u32_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_s16)(op); } @@ -3039,7 +3050,7 @@ TYPE(svuint32) test_svreinterpret_u32_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint32) test_svreinterpret_u32_s32(TYPE(svint32) op) +TYPE(svuint32) test_svreinterpret_u32_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_s32)(op); } @@ -3084,7 +3095,7 @@ TYPE(svuint32) test_svreinterpret_u32_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_s64(TYPE(svint64) op) +TYPE(svuint32) test_svreinterpret_u32_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_s64)(op); } @@ -3129,7 +3140,7 @@ TYPE(svuint32) test_svreinterpret_u32_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_u8(TYPE(svuint8) op) +TYPE(svuint32) test_svreinterpret_u32_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_u8)(op); } @@ -3174,7 +3185,7 @@ TYPE(svuint32) test_svreinterpret_u32_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_u16(TYPE(svuint16) op) +TYPE(svuint32) test_svreinterpret_u32_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_u16)(op); } @@ -3211,7 +3222,7 @@ TYPE(svuint32) test_svreinterpret_u32_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint32) test_svreinterpret_u32_u32(TYPE(svuint32) op) +TYPE(svuint32) test_svreinterpret_u32_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_u32)(op); } @@ -3256,7 +3267,7 @@ TYPE(svuint32) test_svreinterpret_u32_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_u64(TYPE(svuint64) op) +TYPE(svuint32) test_svreinterpret_u32_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_u64)(op); } @@ -3301,7 +3312,7 @@ TYPE(svuint32) test_svreinterpret_u32_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_f16(TYPE(svfloat16) op) +TYPE(svuint32) test_svreinterpret_u32_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_f16)(op); } @@ -3346,7 +3357,7 @@ TYPE(svuint32) test_svreinterpret_u32_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_f32(TYPE(svfloat32) op) +TYPE(svuint32) test_svreinterpret_u32_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_f32)(op); } @@ -3391,7 +3402,7 @@ TYPE(svuint32) test_svreinterpret_u32_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint32) test_svreinterpret_u32_f64(TYPE(svfloat64) op) +TYPE(svuint32) test_svreinterpret_u32_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u32,_f64)(op); } @@ -3436,7 +3447,7 @@ TYPE(svuint32) test_svreinterpret_u32_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_s8(TYPE(svint8) op) +TYPE(svuint64) test_svreinterpret_u64_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_s8)(op); } @@ -3481,7 +3492,7 @@ TYPE(svuint64) test_svreinterpret_u64_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_s16(TYPE(svint16) op) +TYPE(svuint64) test_svreinterpret_u64_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_s16)(op); } @@ -3526,7 +3537,7 @@ TYPE(svuint64) test_svreinterpret_u64_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_s32(TYPE(svint32) op) +TYPE(svuint64) test_svreinterpret_u64_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_s32)(op); } @@ -3563,7 +3574,7 @@ TYPE(svuint64) test_svreinterpret_u64_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint64) test_svreinterpret_u64_s64(TYPE(svint64) op) +TYPE(svuint64) test_svreinterpret_u64_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_s64)(op); } @@ -3608,7 +3619,7 @@ TYPE(svuint64) test_svreinterpret_u64_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_u8(TYPE(svuint8) op) +TYPE(svuint64) test_svreinterpret_u64_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_u8)(op); } @@ -3653,7 +3664,7 @@ TYPE(svuint64) test_svreinterpret_u64_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_u16(TYPE(svuint16) op) +TYPE(svuint64) test_svreinterpret_u64_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_u16)(op); } @@ -3698,7 +3709,7 @@ TYPE(svuint64) test_svreinterpret_u64_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_u32(TYPE(svuint32) op) +TYPE(svuint64) test_svreinterpret_u64_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_u32)(op); } @@ -3735,7 +3746,7 @@ TYPE(svuint64) test_svreinterpret_u64_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svuint64) test_svreinterpret_u64_u64(TYPE(svuint64) op) +TYPE(svuint64) test_svreinterpret_u64_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_u64)(op); } @@ -3780,7 +3791,7 @@ TYPE(svuint64) test_svreinterpret_u64_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_f16(TYPE(svfloat16) op) +TYPE(svuint64) test_svreinterpret_u64_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_f16)(op); } @@ -3825,7 +3836,7 @@ TYPE(svuint64) test_svreinterpret_u64_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_f32(TYPE(svfloat32) op) +TYPE(svuint64) test_svreinterpret_u64_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_f32)(op); } @@ -3870,7 +3881,7 @@ TYPE(svuint64) test_svreinterpret_u64_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svuint64) test_svreinterpret_u64_f64(TYPE(svfloat64) op) +TYPE(svuint64) test_svreinterpret_u64_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_u64,_f64)(op); } @@ -3915,7 +3926,7 @@ TYPE(svuint64) test_svreinterpret_u64_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_s8(TYPE(svint8) op) +TYPE(svfloat16) test_svreinterpret_f16_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_s8)(op); } @@ -3960,7 +3971,7 @@ TYPE(svfloat16) test_svreinterpret_f16_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_s16(TYPE(svint16) op) +TYPE(svfloat16) test_svreinterpret_f16_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_s16)(op); } @@ -4005,7 +4016,7 @@ TYPE(svfloat16) test_svreinterpret_f16_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_s32(TYPE(svint32) op) +TYPE(svfloat16) test_svreinterpret_f16_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_s32)(op); } @@ -4050,7 +4061,7 @@ TYPE(svfloat16) test_svreinterpret_f16_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_s64(TYPE(svint64) op) +TYPE(svfloat16) test_svreinterpret_f16_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_s64)(op); } @@ -4095,7 +4106,7 @@ TYPE(svfloat16) test_svreinterpret_f16_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_u8(TYPE(svuint8) op) +TYPE(svfloat16) test_svreinterpret_f16_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_u8)(op); } @@ -4140,7 +4151,7 @@ TYPE(svfloat16) test_svreinterpret_f16_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_u16(TYPE(svuint16) op) +TYPE(svfloat16) test_svreinterpret_f16_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_u16)(op); } @@ -4185,7 +4196,7 @@ TYPE(svfloat16) test_svreinterpret_f16_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_u32(TYPE(svuint32) op) +TYPE(svfloat16) test_svreinterpret_f16_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_u32)(op); } @@ -4230,7 +4241,7 @@ TYPE(svfloat16) test_svreinterpret_f16_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_u64(TYPE(svuint64) op) +TYPE(svfloat16) test_svreinterpret_f16_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_u64)(op); } @@ -4267,7 +4278,7 @@ TYPE(svfloat16) test_svreinterpret_f16_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svfloat16) test_svreinterpret_f16_f16(TYPE(svfloat16) op) +TYPE(svfloat16) test_svreinterpret_f16_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_f16)(op); } @@ -4312,7 +4323,7 @@ TYPE(svfloat16) test_svreinterpret_f16_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_f32(TYPE(svfloat32) op) +TYPE(svfloat16) test_svreinterpret_f16_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_f32)(op); } @@ -4357,7 +4368,7 @@ TYPE(svfloat16) test_svreinterpret_f16_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat16) test_svreinterpret_f16_f64(TYPE(svfloat64) op) +TYPE(svfloat16) test_svreinterpret_f16_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f16,_f64)(op); } @@ -4402,7 +4413,7 @@ TYPE(svfloat16) test_svreinterpret_f16_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_s8(TYPE(svint8) op) +TYPE(svfloat32) test_svreinterpret_f32_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_s8)(op); } @@ -4447,7 +4458,7 @@ TYPE(svfloat32) test_svreinterpret_f32_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_s16(TYPE(svint16) op) +TYPE(svfloat32) test_svreinterpret_f32_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_s16)(op); } @@ -4492,7 +4503,7 @@ TYPE(svfloat32) test_svreinterpret_f32_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_s32(TYPE(svint32) op) +TYPE(svfloat32) test_svreinterpret_f32_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_s32)(op); } @@ -4537,7 +4548,7 @@ TYPE(svfloat32) test_svreinterpret_f32_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_s64(TYPE(svint64) op) +TYPE(svfloat32) test_svreinterpret_f32_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_s64)(op); } @@ -4582,7 +4593,7 @@ TYPE(svfloat32) test_svreinterpret_f32_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_u8(TYPE(svuint8) op) +TYPE(svfloat32) test_svreinterpret_f32_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_u8)(op); } @@ -4627,7 +4638,7 @@ TYPE(svfloat32) test_svreinterpret_f32_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_u16(TYPE(svuint16) op) +TYPE(svfloat32) test_svreinterpret_f32_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_u16)(op); } @@ -4672,7 +4683,7 @@ TYPE(svfloat32) test_svreinterpret_f32_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_u32(TYPE(svuint32) op) +TYPE(svfloat32) test_svreinterpret_f32_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_u32)(op); } @@ -4717,7 +4728,7 @@ TYPE(svfloat32) test_svreinterpret_f32_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_u64(TYPE(svuint64) op) +TYPE(svfloat32) test_svreinterpret_f32_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_u64)(op); } @@ -4762,7 +4773,7 @@ TYPE(svfloat32) test_svreinterpret_f32_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_f16(TYPE(svfloat16) op) +TYPE(svfloat32) test_svreinterpret_f32_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_f16)(op); } @@ -4799,7 +4810,7 @@ TYPE(svfloat32) test_svreinterpret_f32_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svfloat32) test_svreinterpret_f32_f32(TYPE(svfloat32) op) +TYPE(svfloat32) test_svreinterpret_f32_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_f32)(op); } @@ -4844,7 +4855,7 @@ TYPE(svfloat32) test_svreinterpret_f32_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat32) test_svreinterpret_f32_f64(TYPE(svfloat64) op) +TYPE(svfloat32) test_svreinterpret_f32_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f32,_f64)(op); } @@ -4889,7 +4900,7 @@ TYPE(svfloat32) test_svreinterpret_f32_f64(TYPE(svfloat64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_s8(TYPE(svint8) op) +TYPE(svfloat64) test_svreinterpret_f64_s8(TYPE(svint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_s8)(op); } @@ -4934,7 +4945,7 @@ TYPE(svfloat64) test_svreinterpret_f64_s8(TYPE(svint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_s16(TYPE(svint16) op) +TYPE(svfloat64) test_svreinterpret_f64_s16(TYPE(svint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_s16)(op); } @@ -4979,7 +4990,7 @@ TYPE(svfloat64) test_svreinterpret_f64_s16(TYPE(svint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_s32(TYPE(svint32) op) +TYPE(svfloat64) test_svreinterpret_f64_s32(TYPE(svint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_s32)(op); } @@ -5024,7 +5035,7 @@ TYPE(svfloat64) test_svreinterpret_f64_s32(TYPE(svint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_s64(TYPE(svint64) op) +TYPE(svfloat64) test_svreinterpret_f64_s64(TYPE(svint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_s64)(op); } @@ -5069,7 +5080,7 @@ TYPE(svfloat64) test_svreinterpret_f64_s64(TYPE(svint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_u8(TYPE(svuint8) op) +TYPE(svfloat64) test_svreinterpret_f64_u8(TYPE(svuint8) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_u8)(op); } @@ -5114,7 +5125,7 @@ TYPE(svfloat64) test_svreinterpret_f64_u8(TYPE(svuint8) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_u16(TYPE(svuint16) op) +TYPE(svfloat64) test_svreinterpret_f64_u16(TYPE(svuint16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_u16)(op); } @@ -5159,7 +5170,7 @@ TYPE(svfloat64) test_svreinterpret_f64_u16(TYPE(svuint16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_u32(TYPE(svuint32) op) +TYPE(svfloat64) test_svreinterpret_f64_u32(TYPE(svuint32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_u32)(op); } @@ -5204,7 +5215,7 @@ TYPE(svfloat64) test_svreinterpret_f64_u32(TYPE(svuint32) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_u64(TYPE(svuint64) op) +TYPE(svfloat64) test_svreinterpret_f64_u64(TYPE(svuint64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_u64)(op); } @@ -5249,7 +5260,7 @@ TYPE(svfloat64) test_svreinterpret_f64_u64(TYPE(svuint64) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_f16(TYPE(svfloat16) op) +TYPE(svfloat64) test_svreinterpret_f64_f16(TYPE(svfloat16) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_f16)(op); } @@ -5294,7 +5305,7 @@ TYPE(svfloat64) test_svreinterpret_f64_f16(TYPE(svfloat16) op) // CPP-TUPLE4-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to // CPP-TUPLE4-NEXT: ret [[TMP0]] // -TYPE(svfloat64) test_svreinterpret_f64_f32(TYPE(svfloat32) op) +TYPE(svfloat64) test_svreinterpret_f64_f32(TYPE(svfloat32) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_f32)(op); } @@ -5331,7 +5342,7 @@ TYPE(svfloat64) test_svreinterpret_f64_f32(TYPE(svfloat32) op) // CPP-TUPLE4-NEXT: entry: // CPP-TUPLE4-NEXT: ret [[OP:%.*]] // -TYPE(svfloat64) test_svreinterpret_f64_f64(TYPE(svfloat64) op) +TYPE(svfloat64) test_svreinterpret_f64_f64(TYPE(svfloat64) op) MODE_ATTR { return SVE_ACLE_FUNC(svreinterpret_f64,_f64)(op); } diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret_from_streaming_mode.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret_from_streaming_mode.c deleted file mode 100644 index f278758361932..0000000000000 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret_from_streaming_mode.c +++ /dev/null @@ -1,35 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK -// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sve -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK -// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -S -O1 -Werror -Wall -o /dev/null %s - -// Note: We need to run this test with '-O1' because oddly enough the svreinterpret is always inlined at -O0. - -#include - -#ifdef SVE_OVERLOADED_FORMS -// A simple used,unused... macro, long enough to represent any SVE builtin. -#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 -#else -#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 -#endif - -// Test that svreinterpret is inlined (because it should be streaming-compatible) -__attribute__((target("sme"))) -// CHECK-LABEL: @test_svreinterpret_s16_s8_from_streaming_mode( -// CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to -// CHECK-NEXT: ret [[TMP0]] -// -// CPP-CHECK-LABEL: @_Z45test_svreinterpret_s16_s8_from_streaming_modeu10__SVInt8_t( -// CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = bitcast [[OP:%.*]] to -// CPP-CHECK-NEXT: ret [[TMP0]] -// -svint16_t test_svreinterpret_s16_s8_from_streaming_mode(svint8_t op) __arm_streaming { - return SVE_ACLE_FUNC(svreinterpret_s16,_s8,,)(op); -} - diff --git a/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c b/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c index fb60c6d100ce6..52a05d010de9b 100644 --- a/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c +++ b/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c @@ -88,3 +88,25 @@ float subscript_float32(svfloat32_t a, size_t b) { double subscript_float64(svfloat64_t a, size_t b) { return a[b]; } + +// CHECK-LABEL: @subscript_write_float32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINS:%.*]] = insertelement [[A:%.*]], float 1.000000e+00, i64 [[B:%.*]] +// CHECK-NEXT: ret [[VECINS]] +// +svfloat32_t subscript_write_float32(svfloat32_t a, size_t b) { + a[b] = 1.0f; + return a; +} + +// CHECK-LABEL: @subscript_read_write_float32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement [[A:%.*]], i64 [[B:%.*]] +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[VECEXT]], 1.000000e+00 +// CHECK-NEXT: [[VECINS:%.*]] = insertelement [[A]], float [[ADD]], i64 [[B]] +// CHECK-NEXT: ret [[VECINS]] +// +svfloat32_t subscript_read_write_float32(svfloat32_t a, size_t b) { + a[b] += 1.0f; + return a; +} diff --git a/clang/test/CodeGen/assume_attr.c b/clang/test/CodeGen/assume_attr.c deleted file mode 100644 index 338a625188af0..0000000000000 --- a/clang/test/CodeGen/assume_attr.c +++ /dev/null @@ -1,58 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu %s -o - | FileCheck %s -// RUN: %clang_cc1 -x c -emit-pch -o %t %s -// RUN: %clang_cc1 -include-pch %t %s -emit-llvm -o - | FileCheck %s - -// TODO: for "foo" and "bar", "after" is not added as it appears "after" the first use or definition respectively. There might be a way to allow that. - -// CHECK: define{{.*}} void @bar() #0 -// CHECK: define{{.*}} void @baz() #1 -// CHECK: declare{{.*}} void @foo() #2 -// CHECK: attributes #0 -// CHECK-SAME: "llvm.assume"="bar:before1,bar:before2,bar:before3,bar:def1,bar:def2" -// CHECK: attributes #1 -// CHECK-SAME: "llvm.assume"="baz:before1,baz:before2,baz:before3,baz:def1,baz:def2,baz:after" -// CHECK: attributes #2 -// CHECK-SAME: "llvm.assume"="foo:before1,foo:before2,foo:before3" - -#ifndef HEADER -#define HEADER - -/// foo: declarations only - -__attribute__((assume("foo:before1"))) void foo(void); - -__attribute__((assume("foo:before2"))) -__attribute__((assume("foo:before3"))) void -foo(void); - -/// baz: static function declarations and a definition - -__attribute__((assume("baz:before1"))) static void baz(void); - -__attribute__((assume("baz:before2"))) -__attribute__((assume("baz:before3"))) static void -baz(void); - -// Definition -__attribute__((assume("baz:def1,baz:def2"))) static void baz(void) { foo(); } - -__attribute__((assume("baz:after"))) static void baz(void); - -/// bar: external function declarations and a definition - -__attribute__((assume("bar:before1"))) void bar(void); - -__attribute__((assume("bar:before2"))) -__attribute__((assume("bar:before3"))) void -bar(void); - -// Definition -__attribute__((assume("bar:def1,bar:def2"))) void bar(void) { baz(); } - -__attribute__((assume("bar:after"))) void bar(void); - -/// back to foo - -__attribute__((assume("foo:after"))) void foo(void); - -#endif diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c index 2c3e6931800cd..628892d5809b4 100644 --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -75,8 +75,8 @@ void TwoVersions(void); // LINUX: define weak_odr ptr @TwoVersions.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: %[[FEAT_INIT:.+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4 -// LINUX: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 59754495 -// LINUX: %[[FEAT_CHECK:.+]] = icmp eq i32 %[[FEAT_JOIN]], 59754495 +// LINUX: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 9422847 +// LINUX: %[[FEAT_CHECK:.+]] = icmp eq i32 %[[FEAT_JOIN]], 9422847 // LINUX: ret ptr @TwoVersions.Z // LINUX: ret ptr @TwoVersions.S // LINUX: call void @llvm.trap @@ -85,8 +85,8 @@ void TwoVersions(void); // WINDOWS: define weak_odr dso_local void @TwoVersions() comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: %[[FEAT_INIT:.+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4 -// WINDOWS: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 59754495 -// WINDOWS: %[[FEAT_CHECK:.+]] = icmp eq i32 %[[FEAT_JOIN]], 59754495 +// WINDOWS: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 9422847 +// WINDOWS: %[[FEAT_CHECK:.+]] = icmp eq i32 %[[FEAT_JOIN]], 9422847 // WINDOWS: call void @TwoVersions.Z() // WINDOWS-NEXT: ret void // WINDOWS: call void @TwoVersions.S() @@ -354,7 +354,7 @@ void OrderDispatchUsageSpecific(void) {} // CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" // CHECK-SAME: "tune-cpu"="ivybridge" -// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+cmov,+crc32,+cx16,+cx8,+evex512,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" +// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+aes,+avx,+avx2,+avx512cd,+avx512f,+bmi,+bmi2,+cmov,+crc32,+cx16,+cx8,+evex512,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" // CHECK-SAME: "tune-cpu"="knl" // CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87" // CHECK-SAME: "tune-cpu"="atom" diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c index 304398678216f..3c2b511157f99 100644 --- a/clang/test/CodeGen/attr-target-x86.c +++ b/clang/test/CodeGen/attr-target-x86.c @@ -59,9 +59,9 @@ void __attribute__((target("avx10.1-512"))) avx10_1_512(void) {} // CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87" "tune-cpu"="i686" // CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" // CHECK-NOT: tune-cpu -// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-aes,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512fp16,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-gfni,-kl,-pclmul,-sha,-sha512,-sm3,-sm4,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-widekl,-xop" "tune-cpu"="i686" +// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-aes,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512f,-avx512fp16,-avx512ifma,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-gfni,-kl,-pclmul,-sha,-sha512,-sm3,-sm4,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-widekl,-xop" "tune-cpu"="i686" // CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+crc32,+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" "tune-cpu"="i686" -// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512fp16,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-sha512,-sm3,-sm4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop" "tune-cpu"="i686" +// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512f,-avx512fp16,-avx512ifma,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-sha512,-sm3,-sm4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop" "tune-cpu"="i686" // CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-avx10.1-256,-avx10.1-512,-vaes" // CHECK-NOT: tune-cpu // CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-3dnow,-3dnowa,-mmx" diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index bcb15969de1c5..93a6ab06081c9 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -11,6 +11,7 @@ typedef unsigned char u8x16 __attribute((vector_size(16))); typedef unsigned short u16x8 __attribute((vector_size(16))); typedef unsigned int u32x4 __attribute((vector_size(16))); typedef unsigned long long u64x2 __attribute((vector_size(16))); +typedef __fp16 f16x8 __attribute((vector_size(16))); typedef float f32x4 __attribute((vector_size(16))); typedef double f64x2 __attribute((vector_size(16))); @@ -813,6 +814,17 @@ void store_f16_f32(float val, __fp16 *addr) { // WEBASSEMBLY-NEXT: ret } +f16x8 splat_f16x8(float a) { + // WEBASSEMBLY: %0 = tail call <8 x half> @llvm.wasm.splat.f16x8(float %a) + // WEBASSEMBLY-NEXT: ret <8 x half> %0 + return __builtin_wasm_splat_f16x8(a); +} + +float extract_lane_f16x8(f16x8 a, int i) { + // WEBASSEMBLY: %0 = tail call float @llvm.wasm.extract.lane.f16x8(<8 x half> %a, i32 %i) + // WEBASSEMBLY-NEXT: ret float %0 + return __builtin_wasm_extract_lane_f16x8(a, i); +} __externref_t externref_null() { return __builtin_wasm_ref_null_extern(); // WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern() diff --git a/clang/test/CodeGen/darwin-target-variant.c b/clang/test/CodeGen/darwin-target-variant.c index 36caaaec1bdb9..9f4b36a790db8 100644 --- a/clang/test/CodeGen/darwin-target-variant.c +++ b/clang/test/CodeGen/darwin-target-variant.c @@ -2,5 +2,5 @@ // CHECK: !llvm.module.flags = !{!0, !1, !2 // CHECK: !0 = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 1]} -// CHECK: !1 = !{i32 4, !"darwin.target_variant.triple", !"x86_64-apple-ios14-macabi"} +// CHECK: !1 = !{i32 2, !"darwin.target_variant.triple", !"x86_64-apple-ios14-macabi"} // CHECK: !2 = !{i32 2, !"darwin.target_variant.SDK Version", [2 x i32] [i32 14, i32 1]} diff --git a/clang/test/CodeGen/fat-lto-objects.c b/clang/test/CodeGen/fat-lto-objects.c index b50567c024fc8..36a73684e7bfe 100644 --- a/clang/test/CodeGen/fat-lto-objects.c +++ b/clang/test/CodeGen/fat-lto-objects.c @@ -62,7 +62,7 @@ // ELF: .llvm.lto -// ASM: .section .llvm.lto,"e",@progbits +// ASM: .section .llvm.lto,"e",@llvm_lto // ASM-NEXT: .Lllvm.embedded.object: // ASM-NEXT: .asciz "BC // ASM-NEXT: .size .Lllvm.embedded.object diff --git a/clang/test/CodeGen/function-target-features.c b/clang/test/CodeGen/function-target-features.c index 0d8bfc7e4e44c..d6a73ff8224b6 100644 --- a/clang/test/CodeGen/function-target-features.c +++ b/clang/test/CodeGen/function-target-features.c @@ -4,7 +4,7 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX-FEATURE // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX-NO-CPU -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx512f -target-feature +avx512er | FileCheck %s -check-prefix=TWO-AVX +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx512f -target-feature +avx512bw | FileCheck %s -check-prefix=TWO-AVX // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu corei7 | FileCheck %s -check-prefix=CORE-CPU // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu corei7 -target-feature +avx | FileCheck %s -check-prefix=CORE-CPU-AND-FEATURES // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-cpu x86-64 | FileCheck %s -check-prefix=X86-64-CPU @@ -17,7 +17,7 @@ void foo(void) {} // AVX-FEATURE: "target-features"{{.*}}+avx // AVX-NO-CPU-NOT: target-cpu -// TWO-AVX: "target-features"={{.*}}+avx512er{{.*}}+avx512f +// TWO-AVX: "target-features"={{.*}}+avx512bw{{.*}}+avx512f // CORE-CPU: "target-cpu"="corei7" // CORE-CPU-AND-FEATURES: "target-cpu"="corei7" "target-features"={{.*}}+avx // X86-64-CPU: "target-cpu"="x86-64" diff --git a/clang/test/CodeGen/functions.c b/clang/test/CodeGen/functions.c index 1bbaa80d653c4..0cc999aa4916e 100644 --- a/clang/test/CodeGen/functions.c +++ b/clang/test/CodeGen/functions.c @@ -61,3 +61,15 @@ static void test9_helper(void) {} void test9(void) { (void) test9_helper; } + +// PR88917: don't crash +int b(); + +int main() { + return b(b); + // CHECK: call i32 @b(ptr noundef @b) +} +int b(int (*f)()){ + return 0; +} +// CHECK-LABEL: define{{.*}} i32 @b(ptr noundef %f) diff --git a/clang/test/CodeGen/nofpclass.c b/clang/test/CodeGen/nofpclass.c index dd90d02f7759b..fc4c64f9b921b 100644 --- a/clang/test/CodeGen/nofpclass.c +++ b/clang/test/CodeGen/nofpclass.c @@ -172,7 +172,7 @@ double2 defined_func_v2f64(double2 a, double2 b, double2 c) { // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_extern_func // CLFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[A:%.*]], double noundef nofpclass(nan inf) [[B:%.*]], half noundef nofpclass(nan inf) [[C:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CLFINITEONLY-NEXT: entry: -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float @extern_func(float noundef nofpclass(nan inf) [[A]], double noundef nofpclass(nan inf) [[B]], half noundef nofpclass(nan inf) [[C]]) #[[ATTR10:[0-9]+]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float @extern_func(float noundef nofpclass(nan inf) [[A]], double noundef nofpclass(nan inf) [[B]], half noundef nofpclass(nan inf) [[C]]) #[[ATTR11:[0-9]+]] // CLFINITEONLY-NEXT: ret float [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone @@ -249,7 +249,7 @@ float call_extern_func(float a, double b, _Float16 c) { // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) double @call_extern_func_vec // CLFINITEONLY-SAME: (double noundef nofpclass(nan inf) [[A_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[B:%.*]], i32 noundef [[C_COERCE:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { // CLFINITEONLY-NEXT: entry: -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) double @extern_func_vec(double noundef nofpclass(nan inf) [[A_COERCE]], <2 x double> noundef nofpclass(nan inf) [[B]], i32 noundef [[C_COERCE]]) #[[ATTR10]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) double @extern_func_vec(double noundef nofpclass(nan inf) [[A_COERCE]], <2 x double> noundef nofpclass(nan inf) [[B]], i32 noundef [[C_COERCE]]) #[[ATTR11]] // CLFINITEONLY-NEXT: ret double [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone @@ -389,7 +389,7 @@ float2 call_extern_func_vec(float2 a, double2 b, half2 c) { // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <2 x float> @defined_complex_func // CLFINITEONLY-SAME: (<2 x float> noundef nofpclass(nan inf) [[A_COERCE:%.*]], double noundef nofpclass(nan inf) [[B_COERCE0:%.*]], double noundef nofpclass(nan inf) [[B_COERCE1:%.*]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] { // CLFINITEONLY-NEXT: entry: -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <2 x float> @extern_complex(<2 x float> noundef nofpclass(nan inf) [[A_COERCE]], double noundef nofpclass(nan inf) [[B_COERCE0]], double noundef nofpclass(nan inf) [[B_COERCE1]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE]]) #[[ATTR10]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <2 x float> @extern_complex(<2 x float> noundef nofpclass(nan inf) [[A_COERCE]], double noundef nofpclass(nan inf) [[B_COERCE0]], double noundef nofpclass(nan inf) [[B_COERCE1]], <2 x half> noundef nofpclass(nan inf) [[C_COERCE]]) #[[ATTR11]] // CLFINITEONLY-NEXT: ret <2 x float> [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone @@ -927,12 +927,14 @@ _Complex _Float16 defined_complex_func_f16_ret(_Complex _Float16 c) { // CLFINITEONLY-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16]], align 8 // CLFINITEONLY-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[CF16]], i64 2 // CLFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2 +// CLFINITEONLY-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR12:[0-9]+]] // CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[INDIRECT_ARG_TEMP]], i64 8 // CLFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[INDIRECT_ARG_TEMP]], align 8 // CLFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8 // CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[CF16_REAL]], i64 0 // CLFINITEONLY-NEXT: [[COERCE5_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[COERCE5_SROA_0_0_VEC_INSERT]], half [[CF16_IMAG]], i64 1 -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) @variadic(float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR10]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) @variadic(float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR11]] +// CLFINITEONLY-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR12]] // CLFINITEONLY-NEXT: ret float [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone @@ -1178,12 +1180,14 @@ float call_variadic(float f32, double f64, _Float16 f16, // CLFINITEONLY-NEXT: [[CF16_REAL:%.*]] = load half, ptr [[CF16]], align 8 // CLFINITEONLY-NEXT: [[CF16_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[CF16]], i64 2 // CLFINITEONLY-NEXT: [[CF16_IMAG:%.*]] = load half, ptr [[CF16_IMAGP]], align 2 +// CLFINITEONLY-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR12]] // CLFINITEONLY-NEXT: [[INDIRECT_ARG_TEMP_IMAGP:%.*]] = getelementptr inbounds i8, ptr [[INDIRECT_ARG_TEMP]], i64 8 // CLFINITEONLY-NEXT: store double [[CF64_COERCE0]], ptr [[INDIRECT_ARG_TEMP]], align 8 // CLFINITEONLY-NEXT: store double [[CF64_COERCE1]], ptr [[INDIRECT_ARG_TEMP_IMAGP]], align 8 // CLFINITEONLY-NEXT: [[COERCE5_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x half> poison, half [[CF16_REAL]], i64 0 // CLFINITEONLY-NEXT: [[COERCE5_SROA_0_2_VEC_INSERT:%.*]] = insertelement <2 x half> [[COERCE5_SROA_0_0_VEC_INSERT]], half [[CF16_IMAG]], i64 1 -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) [[FPTR]](float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR10]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) float (float, ...) [[FPTR]](float noundef nofpclass(nan inf) [[F32]], double noundef nofpclass(nan inf) [[CONV]], double noundef nofpclass(nan inf) [[F64]], half noundef nofpclass(nan inf) [[F16]], double noundef nofpclass(nan inf) [[V2F32_COERCE]], <2 x double> noundef nofpclass(nan inf) [[V2F64]], i32 noundef [[V2F16_COERCE]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE]], ptr noundef nonnull byval({ double, double }) align 8 [[INDIRECT_ARG_TEMP]], <2 x half> noundef nofpclass(nan inf) [[COERCE5_SROA_0_2_VEC_INSERT]]) #[[ATTR11]] +// CLFINITEONLY-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[INDIRECT_ARG_TEMP]]) #[[ATTR12]] // CLFINITEONLY-NEXT: ret float [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone @@ -1364,9 +1368,9 @@ extern __m256d extern_m256d(__m256d, ...); // // CLFINITEONLY: Function Attrs: convergent norecurse nounwind // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <4 x double> @call_m256d -// CLFINITEONLY-SAME: (<4 x double> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { +// CLFINITEONLY-SAME: (<4 x double> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] { // CLFINITEONLY-NEXT: entry: -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <4 x double> (<4 x double>, ...) @extern_m256d(<4 x double> noundef nofpclass(nan inf) [[X]], <4 x double> noundef nofpclass(nan inf) [[X]]) #[[ATTR10]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <4 x double> (<4 x double>, ...) @extern_m256d(<4 x double> noundef nofpclass(nan inf) [[X]], <4 x double> noundef nofpclass(nan inf) [[X]]) #[[ATTR11]] // CLFINITEONLY-NEXT: ret <4 x double> [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone @@ -1407,9 +1411,9 @@ __m256d call_m256d(__m256d x) { // // CLFINITEONLY: Function Attrs: convergent norecurse nounwind // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) <25 x double> @call_matrix -// CLFINITEONLY-SAME: (<25 x double> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] { +// CLFINITEONLY-SAME: (<25 x double> noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR10:[0-9]+]] { // CLFINITEONLY-NEXT: entry: -// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <25 x double> @extern_matrix(<25 x double> noundef nofpclass(nan inf) [[X]]) #[[ATTR10]] +// CLFINITEONLY-NEXT: [[CALL:%.*]] = tail call nnan ninf nofpclass(nan inf) <25 x double> @extern_matrix(<25 x double> noundef nofpclass(nan inf) [[X]]) #[[ATTR11]] // CLFINITEONLY-NEXT: ret <25 x double> [[CALL]] // // NONANS: Function Attrs: noinline nounwind optnone diff --git a/clang/test/CodeGen/target-builtin-noerror.c b/clang/test/CodeGen/target-builtin-noerror.c index b438e50848a4b..2e16fd8b9fe4d 100644 --- a/clang/test/CodeGen/target-builtin-noerror.c +++ b/clang/test/CodeGen/target-builtin-noerror.c @@ -68,8 +68,6 @@ void verifyfeaturestrings(void) { (void)__builtin_cpu_supports("avx512bw"); (void)__builtin_cpu_supports("avx512dq"); (void)__builtin_cpu_supports("avx512cd"); - (void)__builtin_cpu_supports("avx512er"); - (void)__builtin_cpu_supports("avx512pf"); (void)__builtin_cpu_supports("avx512vbmi"); (void)__builtin_cpu_supports("avx512ifma"); (void)__builtin_cpu_supports("avx5124vnniw"); diff --git a/clang/test/CodeGenCXX/assume_attr.cpp b/clang/test/CodeGenCXX/assume_attr.cpp index dbe76501377c0..962dcc470f676 100644 --- a/clang/test/CodeGenCXX/assume_attr.cpp +++ b/clang/test/CodeGenCXX/assume_attr.cpp @@ -8,77 +8,77 @@ /// foo: declarations only -__attribute__((assume("foo:before1"))) void foo(); +[[omp::assume("foo:before1")]] void foo(); -__attribute__((assume("foo:before2"))) -__attribute__((assume("foo:before3"))) void +[[omp::assume("foo:before2")]] +[[omp::assume("foo:before3")]] void foo(); /// baz: static function declarations and a definition -__attribute__((assume("baz:before1"))) static void baz(); +[[omp::assume("baz:before1")]] static void baz(); -__attribute__((assume("baz:before2"))) -__attribute__((assume("baz:before3"))) static void +[[omp::assume("baz:before2")]] +[[omp::assume("baz:before3")]] static void baz(); // Definition -__attribute__((assume("baz:def1,baz:def2"))) static void baz() { foo(); } +[[omp::assume("baz:def1,baz:def2")]] static void baz() { foo(); } -__attribute__((assume("baz:after"))) static void baz(); +[[omp::assume("baz:after")]] static void baz(); /// bar: external function declarations and a definition -__attribute__((assume("bar:before1"))) void bar(); +[[omp::assume("bar:before1")]] void bar(); -__attribute__((assume("bar:before2"))) -__attribute__((assume("bar:before3"))) void +[[omp::assume("bar:before2")]] +[[omp::assume("bar:before3")]] void bar(); // Definition -__attribute__((assume("bar:def1,bar:def2"))) void bar() { baz(); } +[[omp::assume("bar:def1,bar:def2")]] void bar() { baz(); } -__attribute__((assume("bar:after"))) void bar(); +[[omp::assume("bar:after")]] void bar(); /// back to foo -__attribute__((assume("foo:after"))) void foo(); +[[omp::assume("foo:after")]] void foo(); /// class tests class C { - __attribute__((assume("C:private_method"))) void private_method(); - __attribute__((assume("C:private_static"))) static void private_static(); + [[omp::assume("C:private_method")]] void private_method(); + [[omp::assume("C:private_static")]] static void private_static(); public: - __attribute__((assume("C:public_method1"))) void public_method(); - __attribute__((assume("C:public_static1"))) static void public_static(); + [[omp::assume("C:public_method1")]] void public_method(); + [[omp::assume("C:public_static1")]] static void public_static(); }; -__attribute__((assume("C:public_method2"))) void C::public_method() { +[[omp::assume("C:public_method2")]] void C::public_method() { private_method(); } -__attribute__((assume("C:public_static2"))) void C::public_static() { +[[omp::assume("C:public_static2")]] void C::public_static() { private_static(); } /// template tests template -__attribute__((assume("template_func"))) void template_func() {} +[[omp::assume("template_func")]] void template_func() {} template <> -__attribute__((assume("template_func"))) void template_func() {} +[[omp::assume("template_func")]] void template_func() {} template <> void template_func() {} template struct S { - __attribute__((assume("S::method"))) void method(); + [[omp::assume("S::method")]] void method(); }; template <> -__attribute__((assume("S::method"))) void S::method() {} +[[omp::assume("S::method")]] void S::method() {} template <> void S::method() {} diff --git a/clang/test/CodeGenCXX/builtin-amdgcn-fence.cpp b/clang/test/CodeGenCXX/builtin-amdgcn-fence.cpp index 630e416b893f4..3af5a21ba0cd5 100644 --- a/clang/test/CodeGenCXX/builtin-amdgcn-fence.cpp +++ b/clang/test/CodeGenCXX/builtin-amdgcn-fence.cpp @@ -1,22 +1,111 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 // REQUIRES: amdgpu-registered-target // RUN: %clang_cc1 %s -emit-llvm -O0 -o - \ -// RUN: -triple=amdgcn-amd-amdhsa | opt -S | FileCheck %s +// RUN: -triple=amdgcn-amd-amdhsa | FileCheck %s +// CHECK-LABEL: define dso_local void @_Z25test_memory_fence_successv( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: fence syncscope("workgroup") seq_cst +// CHECK-NEXT: fence syncscope("agent") acquire +// CHECK-NEXT: fence seq_cst +// CHECK-NEXT: fence syncscope("agent") acq_rel +// CHECK-NEXT: fence syncscope("workgroup") release +// CHECK-NEXT: ret void +// void test_memory_fence_success() { - // CHECK-LABEL: test_memory_fence_success - // CHECK: fence syncscope("workgroup") seq_cst __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "workgroup"); - // CHECK: fence syncscope("agent") acquire __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, "agent"); - // CHECK: fence seq_cst __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, ""); - // CHECK: fence syncscope("agent") acq_rel __builtin_amdgcn_fence(4, "agent"); - // CHECK: fence syncscope("workgroup") release __builtin_amdgcn_fence(3, "workgroup"); } + +// CHECK-LABEL: define dso_local void @_Z10test_localv( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: fence syncscope("workgroup") seq_cst, !mmra [[META3:![0-9]+]] +// CHECK-NEXT: fence syncscope("agent") acquire, !mmra [[META3]] +// CHECK-NEXT: fence seq_cst, !mmra [[META3]] +// CHECK-NEXT: fence syncscope("agent") acq_rel, !mmra [[META3]] +// CHECK-NEXT: fence syncscope("workgroup") release, !mmra [[META3]] +// CHECK-NEXT: ret void +// +void test_local() { + __builtin_amdgcn_fence( __ATOMIC_SEQ_CST, "workgroup", "local"); + + __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, "agent", "local"); + + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "", "local"); + + __builtin_amdgcn_fence(4, "agent", "local"); + + __builtin_amdgcn_fence(3, "workgroup", "local"); +} + + +// CHECK-LABEL: define dso_local void @_Z11test_globalv( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: fence syncscope("workgroup") seq_cst, !mmra [[META4:![0-9]+]] +// CHECK-NEXT: fence syncscope("agent") acquire, !mmra [[META4]] +// CHECK-NEXT: fence seq_cst, !mmra [[META4]] +// CHECK-NEXT: fence syncscope("agent") acq_rel, !mmra [[META4]] +// CHECK-NEXT: fence syncscope("workgroup") release, !mmra [[META4]] +// CHECK-NEXT: ret void +// +void test_global() { + __builtin_amdgcn_fence( __ATOMIC_SEQ_CST, "workgroup", "global"); + + __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, "agent", "global"); + + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "", "global"); + + __builtin_amdgcn_fence(4, "agent", "global"); + + __builtin_amdgcn_fence(3, "workgroup", "global"); +} + +// CHECK-LABEL: define dso_local void @_Z10test_imagev( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: fence syncscope("workgroup") seq_cst, !mmra [[META3]] +// CHECK-NEXT: fence syncscope("agent") acquire, !mmra [[META3]] +// CHECK-NEXT: fence seq_cst, !mmra [[META3]] +// CHECK-NEXT: fence syncscope("agent") acq_rel, !mmra [[META3]] +// CHECK-NEXT: fence syncscope("workgroup") release, !mmra [[META3]] +// CHECK-NEXT: ret void +// +void test_image() { + __builtin_amdgcn_fence( __ATOMIC_SEQ_CST, "workgroup", "local"); + + __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, "agent", "local"); + + __builtin_amdgcn_fence(__ATOMIC_SEQ_CST, "", "local"); + + __builtin_amdgcn_fence(4, "agent", "local"); + + __builtin_amdgcn_fence(3, "workgroup", "local"); +} + +// CHECK-LABEL: define dso_local void @_Z10test_mixedv( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: fence syncscope("workgroup") seq_cst, !mmra [[META5:![0-9]+]] +// CHECK-NEXT: fence syncscope("workgroup") seq_cst, !mmra [[META5]] +// CHECK-NEXT: ret void +// +void test_mixed() { + __builtin_amdgcn_fence( __ATOMIC_SEQ_CST, "workgroup", "local", "global"); + __builtin_amdgcn_fence( __ATOMIC_SEQ_CST, "workgroup", "local", "local", "global", "local", "local"); +} +//. +// CHECK: [[META3]] = !{!"amdgpu-as", !"local"} +// CHECK: [[META4]] = !{!"amdgpu-as", !"global"} +// CHECK: [[META5]] = !{[[META4]], [[META3]]} +//. diff --git a/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp b/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp index 4e15657251525..55913aff9c19b 100644 --- a/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp +++ b/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp @@ -1,12 +1,12 @@ // Check that delete exprs call the sized deallocation function if -// -fsized-deallocation is passed in both C++11 and C++14. +// -fsized-deallocation is passed in C++11 or std >= C++14. // RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++14 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s -// Check that we don't used sized deallocation without -fsized-deallocation and -// C++14. +// Check that we don't used sized deallocation with -fno-sized-deallocation or without C++14. // RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED -// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED +// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -triple x86_64-linux-gnu -fno-sized-deallocation -o - \ +// RUN: | FileCheck %s --check-prefix=CHECK-UNSIZED // CHECK-UNSIZED-NOT: _ZdlPvm // CHECK-UNSIZED-NOT: _ZdaPvm diff --git a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp index ab2e4b3cdbbf9..8823bc64a4368 100644 --- a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp +++ b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp @@ -1,10 +1,10 @@ // Check that delete exprs call aligned (de)allocation functions if // -faligned-allocation is passed in both C++11 and C++14. // RUN: %clang_cc1 -std=c++11 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++14 -fexceptions -fsized-deallocation -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -fexceptions -faligned-allocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++1z -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++1z -fexceptions -fsized-deallocation %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefix=CHECK-MS +// RUN: %clang_cc1 -std=c++1z -fexceptions %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s --check-prefix=CHECK-MS // Check that we don't used aligned (de)allocation without -faligned-allocation or C++1z. // RUN: %clang_cc1 -std=c++14 -DUNALIGNED -fexceptions %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNALIGNED diff --git a/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp b/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp index 20264b67353a9..f6f4a2ff735cc 100644 --- a/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp +++ b/clang/test/CodeGenCXX/cxx2a-destroying-delete.cpp @@ -108,10 +108,10 @@ struct J { // CHECK-MSABI-LABEL: define {{.*}}@"?j@@ J *j() { // CHECK-ITANIUM: invoke {{.*}}@_ZN1JC1Ev( - // CHECK-ITANIUM: call {{.*}}@_ZdlPv( + // CHECK-ITANIUM: call {{.*}}@_ZdlPvm( // CHECK-NOT: } // CHECK-MSABI: invoke {{.*}}@"??0J@@Q{{AE|EAA}}@XZ"( - // CHECK-MSABI: call {{.*}}@"??3@YAXP{{E?}}AX@Z"( + // CHECK-MSABI: call {{.*}}@"??3@YAXP{{E?}}AX{{I|_K}}@Z"( return new J; // CHECK: } } diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp index b755e80db35a1..649fe2afbf4e9 100644 --- a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp +++ b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp @@ -182,3 +182,66 @@ auto dothing(int num) fun(); } } + +namespace GH87210 { +template +struct Overloaded : Ts... { + using Ts::operator()...; +}; + +template +Overloaded(Ts...) -> Overloaded; + +// CHECK-LABEL: define dso_local void @_ZN7GH872101fEv() +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X:%.*]] = alloca i32 +// CHECK-NEXT: [[Over:%.*]] = alloca %"{{.*}}Overloaded" +// CHECK: call noundef ptr @"_ZZN7GH872101fEvENH3$_0clINS_10OverloadedIJS0_EEEEEDaRT_"(ptr {{.*}} [[Over]]) +void f() { + int x; + Overloaded o { + // CHECK: define internal noundef ptr @"_ZZN7GH872101fEvENH3$_0clINS_10OverloadedIJS0_EEEEEDaRT_"(ptr {{.*}} [[Self:%.*]]) + // CHECK-NEXT: entry: + // CHECK-NEXT: [[SelfAddr:%.*]] = alloca ptr + // CHECK-NEXT: store ptr [[Self]], ptr [[SelfAddr]] + // CHECK-NEXT: [[SelfPtr:%.*]] = load ptr, ptr [[SelfAddr]] + // CHECK-NEXT: [[XRef:%.*]] = getelementptr inbounds %{{.*}}, ptr [[SelfPtr]], i32 0, i32 0 + // CHECK-NEXT: [[X:%.*]] = load ptr, ptr [[XRef]] + // CHECK-NEXT: ret ptr [[X]] + [&](this auto& self) { + return &x; + } + }; + o(); +} + +void g() { + int x; + Overloaded o { + [=](this auto& self) { + return x; + } + }; + o(); +} +} + +namespace GH89541 { +// Same as above; just check that this doesn't crash. +int one = 1; +auto factory(int& x = one) { + return [&](this auto self) { + x; + }; +}; + +using Base = decltype(factory()); +struct Derived : Base { + Derived() : Base(factory()) {} +}; + +void f() { + Derived d; + d(); +} +} diff --git a/clang/test/CodeGenCXX/delete-two-arg.cpp b/clang/test/CodeGenCXX/delete-two-arg.cpp index 552634f430a80..a0dcd03bc5a92 100644 --- a/clang/test/CodeGenCXX/delete-two-arg.cpp +++ b/clang/test/CodeGenCXX/delete-two-arg.cpp @@ -43,7 +43,9 @@ namespace test2 { // CHECK-NEXT: br i1 [[T1]], // CHECK: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i32 -4 // CHECK-NEXT: [[T5:%.*]] = load i32, ptr [[T3]] - // CHECK-NEXT: call void @_ZdaPv(ptr noundef [[T3]]) + // CHECK-NEXT: [[T6:%.*]] = mul i32 4, [[T5]] + // CHECK-NEXT: [[T7:%.*]] = add i32 [[T6]], 4 + // CHECK-NEXT: call void @_ZdaPvj(ptr noundef [[T3]], i32 noundef [[T7]]) // CHECK-NEXT: br label ::delete[] p; } diff --git a/clang/test/CodeGenCXX/delete.cpp b/clang/test/CodeGenCXX/delete.cpp index 1a418f48b6598..d5b0dc6712910 100644 --- a/clang/test/CodeGenCXX/delete.cpp +++ b/clang/test/CodeGenCXX/delete.cpp @@ -16,7 +16,7 @@ void t3(S *s) { // CHECK: icmp {{.*}} null // CHECK: br i1 - // CHECK: call void @_ZdlPv + // CHECK: call void @_ZdlPvm // Check the delete is inside the 'if !null' check unless we're optimizing // for size. FIXME: We could omit the branch entirely in this case. @@ -35,7 +35,7 @@ struct T { void t4(T *t) { // CHECK: call void @_ZN1TD1Ev // CHECK-SIZE-NEXT: br - // CHECK: call void @_ZdlPv + // CHECK: call void @_ZdlPvm delete t; } @@ -93,14 +93,16 @@ namespace test1 { // CHECK-NEXT: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[CUR]]) // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[ISDONE]] - // CHECK: call void @_ZdaPv(ptr noundef [[ALLOC]]) + // CHECK: [[MUL:%.*]] = mul i64 4, [[COUNT]] + // CHECK-NEXT: [[SIZE:%.*]] = add i64 [[MUL]], 8 + // CHECK-NEXT: call void @_ZdaPvm(ptr noundef [[ALLOC]], i64 noundef [[SIZE]]) } } namespace test2 { // CHECK-LABEL: define{{.*}} void @_ZN5test21fEPb void f(bool *b) { - // CHECK: call void @_ZdlPv(ptr + // CHECK: call void @_ZdlPvm(ptr{{.*}}i64 delete b; // CHECK: call void @_ZdaPv(ptr delete [] b; @@ -137,7 +139,7 @@ namespace test4 { // CHECK-NEXT: [[DTOR:%.*]] = load ptr, ptr [[T0]] // CHECK-NEXT: call void [[DTOR]](ptr {{[^,]*}} [[OBJ:%.*]]) // Call the global operator delete. - // CHECK-NEXT: call void @_ZdlPv(ptr noundef [[ALLOCATED]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: call void @_ZdlPvm(ptr noundef [[ALLOCATED]], i64 noundef 8) [[NUW:#[0-9]+]] ::delete xp; } } diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp index 6fec2f2982d40..484866b45389f 100644 --- a/clang/test/CodeGenCXX/dllimport.cpp +++ b/clang/test/CodeGenCXX/dllimport.cpp @@ -205,7 +205,7 @@ USEVAR(VarTmpl) // Functions //===----------------------------------------------------------------------===// -// GNU-DAG: declare dso_local void @_ZdlPv(ptr) +// GNU-DAG: declare dso_local void @_ZdlPv{{j|y}}(ptr, i{{32|64}}) // Import function declaration. // MSC-DAG: declare dllimport void @"?decl@@YAXXZ"() @@ -358,7 +358,7 @@ __declspec(dllimport) void operator delete(void*); __declspec(dllimport) inline int *ReferencingImportedNew() { return new int[2]; } // MO1-DAG: define available_externally dllimport ptr @"?ReferencingImportedNew@@YAPAHXZ" __declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nullptr; } -// MO1-DAG: define available_externally dllimport ptr @"?ReferencingImportedDelete@@YAPAHXZ" +// MO1-DAG: declare dllimport ptr @"?ReferencingImportedDelete@@YAPAHXZ" USE(ReferencingImportedNew) USE(ReferencingImportedDelete) struct ClassWithDtor { ~ClassWithDtor() {} }; diff --git a/clang/test/CodeGenCXX/fmv-namespace.cpp b/clang/test/CodeGenCXX/fmv-namespace.cpp new file mode 100644 index 0000000000000..5bcd0da06eebc --- /dev/null +++ b/clang/test/CodeGenCXX/fmv-namespace.cpp @@ -0,0 +1,93 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 5 +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s + +namespace Name { +int __attribute((target_version("default"))) foo() { return 0; } +} + +namespace Name { +int __attribute((target_version("sve"))) foo() { return 1; } +} + +int bar() { return Name::foo(); } + +namespace OtherName { +int __attribute((target_version("sve"))) foo() { return 2; } +} + +int baz() { return OtherName::foo(); } + +//. +// CHECK: @__aarch64_cpu_features = external dso_local global { i64 } +// CHECK: @_ZN4Name3fooEv.ifunc = weak_odr alias i32 (), ptr @_ZN4Name3fooEv +// CHECK: @_ZN9OtherName3fooEv.ifunc = weak_odr alias i32 (), ptr @_ZN9OtherName3fooEv +// CHECK: @_ZN4Name3fooEv = weak_odr ifunc i32 (), ptr @_ZN4Name3fooEv.resolver +// CHECK: @_ZN9OtherName3fooEv = weak_odr ifunc i32 (), ptr @_ZN9OtherName3fooEv.resolver +//. +// CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv.default( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret i32 0 +// +// +// CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv._Msve( +// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret i32 1 +// +// +// CHECK-LABEL: define dso_local noundef i32 @_Z3barv( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN4Name3fooEv() +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: +// CHECK-NEXT: ret ptr @_ZN4Name3fooEv._Msve +// CHECK: [[RESOLVER_ELSE]]: +// CHECK-NEXT: ret ptr @_ZN4Name3fooEv.default +// +// +// CHECK-LABEL: define dso_local noundef i32 @_ZN9OtherName3fooEv._Msve( +// CHECK-SAME: ) #[[ATTR1]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret i32 2 +// +// +// CHECK-LABEL: define dso_local noundef i32 @_Z3bazv( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN9OtherName3fooEv() +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK-LABEL: define weak_odr ptr @_ZN9OtherName3fooEv.resolver() comdat { +// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] +// CHECK: [[RESOLVER_RETURN]]: +// CHECK-NEXT: ret ptr @_ZN9OtherName3fooEv._Msve +// CHECK: [[RESOLVER_ELSE]]: +// CHECK-NEXT: ret ptr @_ZN9OtherName3fooEv.default +// +//. +// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } +// CHECK: attributes #[[ATTR2:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +//. +// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} +//. diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp index e278d9acfe9ee..af225529c494e 100644 --- a/clang/test/CodeGenCXX/new.cpp +++ b/clang/test/CodeGenCXX/new.cpp @@ -15,7 +15,7 @@ void t1() { } // CHECK: declare noundef nonnull ptr @_Znwm(i64 noundef) [[ATTR_NOBUILTIN:#[^ ]*]] -// CHECK: declare void @_ZdlPv(ptr noundef) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] +// CHECK: declare void @_ZdlPvm(ptr noundef, i64 noundef) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]] // CHECK: declare noundef nonnull ptr @_Znam(i64 noundef) [[ATTR_NOBUILTIN]] // CHECK: declare void @_ZdaPv(ptr noundef) [[ATTR_NOBUILTIN_NOUNWIND]] @@ -192,7 +192,7 @@ void f() { // CHECK: store i64 200 delete[] new (nothrow) Alloc[10][20]; // CHECK: call noalias noundef nonnull ptr @_Znwm - // CHECK: call void @_ZdlPv(ptr + // CHECK: call void @_ZdlPvm(ptr noundef {{%.*}}, i64 noundef 1) delete new bool; // CHECK: ret void } @@ -317,7 +317,7 @@ namespace N3664 { void f() { // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] int *p = new int; // expected-note {{allocated with 'new' here}} - // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]] + // CHECK: call void @_ZdlPvm({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]] delete p; // CHECK: call noalias noundef nonnull ptr @_Znam(i64 noundef 12) [[ATTR_BUILTIN_NEW]] diff --git a/clang/test/CodeGenCXX/ps-dllstorage-vtable-rtti.cpp b/clang/test/CodeGenCXX/ps-dllstorage-vtable-rtti.cpp new file mode 100644 index 0000000000000..377e579058ac1 --- /dev/null +++ b/clang/test/CodeGenCXX/ps-dllstorage-vtable-rtti.cpp @@ -0,0 +1,114 @@ +/// For a class that has a vtable and typeinfo symbol for RTTI, if a user marks +/// either: +/// +/// (a) The entire class as dllexport (dllimport) +/// (b) Any non-inline method of the class as dllexport (dllimport) +/// +/// then Clang must export the vtable and typeinfo symbol from the TU where they +/// are defined (the TU containing the definition of the Itanium C++ ABI "key +/// function") and must import them in other modules where they are referenced. + +// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-unknown-windows-itanium -emit-llvm -o - %s -fhalf-no-semantic-interposition \ +// RUN: | FileCheck %s -check-prefix=WI +// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-scei-windows-itanium -emit-llvm -o - %s -fhalf-no-semantic-interposition \ +// RUN: | FileCheck %s --check-prefixes=PS +// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-scei-ps4 -emit-llvm -o - %s -fhalf-no-semantic-interposition \ +// RUN: | FileCheck %s --check-prefixes=PS +// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-sie-ps5 -emit-llvm -o - %s -fhalf-no-semantic-interposition \ +// RUN: | FileCheck %s --check-prefixes=PS + +#include + +/// Case (a) -- Import Aspect +/// The entire class is imported. The typeinfo symbol must also be imported, but +/// the vtable will not be referenced, and so does not need to be imported. + +// PS-DAG: @_ZTI10FullImport = {{.*}}dllimport +// WI-DAG: @_ZTI10FullImport = external dllimport constant ptr +struct __declspec(dllimport) FullImport { + virtual void inlineFunc() const {} + virtual void key(); + virtual void func(); +}; + +/// 'FullImport::key()' is the key function, so the vtable and typeinfo symbol +/// of 'FullImport' will be defined in the TU that contains the definition of +/// 'key()' (and they must be exported from there). +void FullImportTest() { typeid(FullImport).name(); } + +/// Case (a) -- Export Aspect +/// The entire class is exported. The vtable and typeinfo symbols must also be +/// exported. + +// PS-DAG: @_ZTV10FullExport = {{.*}}dllexport +// WI-DAG: @_ZTV10FullExport = {{.*}}dllexport +// PS-DAG: @_ZTI10FullExport = {{.*}}dllexport +// WI-DAG: @_ZTI10FullExport = dso_local dllexport constant { +struct __declspec(dllexport) FullExport { + virtual void inlineFunc() const {} + virtual void key(); + virtual void func(); +}; + +/// This is the key function of the class 'FullExport', so the vtable and +/// typeinfo symbols of 'FullExport' will be defined in this TU, and so they +/// must be exported from this TU. +void FullExport::key() { typeid(FullExport).name(); } + +/// Case (b) -- Import Aspect +/// The class as a whole is not imported, but a non-inline method of the class +/// is, so the vtable and typeinfo symbol must be imported. + +// PS-DAG: @_ZTV10PartImport = {{.*}}dllimport +// WI-DAG: @_ZTV10PartImport = external dso_local unnamed_addr constant { +// PS-DAG: @_ZTI10PartImport = {{.*}}dllimport +// WI-DAG: @_ZTI10PartImport = external dso_local constant ptr +struct PartImport { + virtual void inlineFunc() const {} + virtual void key(); + __declspec(dllimport) virtual void func(); +}; + +/// 'PartImport::key()' is the key function, so the vtable and typeinfo symbol +/// of 'PartImport' will be defined in the TU that contains the definition of +/// 'key()' (and they must be exported from there). Here, we will reference the +/// vtable and typeinfo symbol, so we must also import them. +void PartImportTest() { + PartImport f; + typeid(PartImport).name(); +} + +/// Case (b) -- Export Aspect +/// The class as a whole is not exported, but a non-inline method of the class +/// is, so the vtable and typeinfo symbol must be exported. + +// PS-DAG: @_ZTV10PartExport = {{.*}}dllexport +// WI-DAG: @_ZTV10PartExport = dso_local unnamed_addr constant { +// PS-DAG: @_ZTI10PartExport = {{.*}}dllexport +// WI-DAG: @_ZTI10PartExport = dso_local constant { +struct PartExport { + virtual void inlineFunc() const {} + virtual void key(); + __declspec(dllexport) virtual void func(); +}; + +/// This is the key function of the class 'PartExport', so the vtable and +/// typeinfo symbol of 'PartExport' will be defined in this TU, and so they must +/// be exported from this TU. +void PartExport::key() { typeid(PartExport).name(); } + +/// Case (b) -- Export Aspect +/// The class as a whole is not exported, but the constructor of the class +/// is, so the vtable and typeinfo symbol must be exported. + +// PS-DAG: @_ZTV10ConsExport = {{.*}}dllexport +// WI-DAG: @_ZTV10ConsExport = dso_local unnamed_addr constant { +// PS-DAG: @_ZTI10ConsExport = {{.*}}dllexport +// WI-DAG: @_ZTI10ConsExport = dso_local constant { +struct ConsExport { + __declspec(dllexport) ConsExport(); + virtual void key(); +}; + +ConsExport::ConsExport() {} +void ConsExport::key() { typeid(ConsExport).name(); } diff --git a/clang/test/CodeGenCXX/ps4-dllstorage-vtable-rtti.cpp b/clang/test/CodeGenCXX/ps4-dllstorage-vtable-rtti.cpp deleted file mode 100644 index 5724e78617df9..0000000000000 --- a/clang/test/CodeGenCXX/ps4-dllstorage-vtable-rtti.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// For a class that has a vtable (and hence, also has a typeinfo symbol for -// RTTI), if a user marks either: -// -// (a) the entire class as dllexport (dllimport), or -// (b) all non-inline virtual methods of the class as dllexport (dllimport) -// -// then Clang must export the vtable and typeinfo symbol from the TU where they -// are defined (the TU containing the definition of the Itanium C++ ABI "key -// function"), and must import them in other modules where they are referenced. -// -// Conversely to point (b), if some (but not all) of the non-inline virtual -// methods of a class are marked as dllexport (dllimport), then the vtable and -// typeinfo symbols must not be exported (imported). This will result in a -// link-time failure when linking the importing module. This link-time failure -// is the desired behavior, because the Microsoft toolchain also gets a -// link-time failure in these cases (and since __declspec(dllexport) -// (__declspec(dllimport)) is a Microsoft extension, our intention is to mimic -// that Microsoft behavior). -// -// Side note: It is within the bodies of constructors (and in some cases, -// destructors) that the vtable is explicitly referenced. In case (a) above, -// where the entire class is exported (imported), then all constructors (among -// other things) are exported (imported). So for that situation, an importing -// module for a well-formed program will not actually reference the vtable, -// since constructor calls will all be to functions external to that module -// (and imported into it, from the exporting module). I.e., all vtable -// references will be in that module where the constructor and destructor -// bodies are, therefore, there will not be a need to import the vtable in -// that case. -// -// This test contains 6 test classes: -// 2 for point (a), -// 2 for point (b), -// and 2 negative tests for the converse of point (b). -// -// The two tests for each of these points are one for importing, and one for -// exporting. - -// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-unknown-windows-itanium -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s -check-prefix=WI -// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-scei-windows-itanium -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefixes=PS4,SCEI_WI -// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-scei-ps4 -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefixes=PS4,SCEI_PS4 -// RUN: %clang_cc1 -I%S -fdeclspec -triple x86_64-sie-ps5 -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefixes=PS4,SCEI_PS4 - -#include - -// Case (a) -- Import Aspect -// The entire class is imported. The typeinfo symbol must also be imported, -// but the vtable will not be referenced, and so does not need to be imported -// (as described in the "Side note", above). -// -// PS4-DAG: @_ZTI10FullImport = {{.*}}dllimport -// WI-DAG: @_ZTI10FullImport = external dllimport constant ptr -struct __declspec(dllimport) FullImport -{ - virtual void getId() {} - virtual void Bump(); - virtual void Decrement(); -}; - -// 'FullImport::Bump()' is the key function, so the vtable and typeinfo symbol -// of 'FullImport' will be defined in the TU that contains the definition of -// 'Bump()' (and they must be exported from there). -void FullImportTest() -{ - typeid(FullImport).name(); -} - -/////////////////////////////////////////////////////////////////// - -// Case (a) -- Export Aspect -// The entire class is exported. The vtable and typeinfo symbols must also be -// exported, -// -// PS4-DAG: @_ZTV10FullExport ={{.*}}dllexport -// WI-DAG: @_ZTV10FullExport ={{.*}}dllexport -// PS4-DAG: @_ZTI10FullExport ={{.*}}dllexport -// WI-DAG: @_ZTI10FullExport = dso_local dllexport constant { -struct __declspec(dllexport) FullExport // Easy case: Entire class is exported. -{ - virtual void getId() {} - virtual void Bump(); - virtual void Decrement(); -}; - -// This is the key function of the class 'FullExport', so the vtable and -// typeinfo symbols of 'FullExport' will be defined in this TU, and so they -// must be exported from this TU. -void FullExport::Bump() -{ - typeid(FullExport).name(); -} - -/////////////////////////////////////////////////////////////////// - -// Case (b) -- Import Aspect -// The class as a whole is not imported, but all non-inline virtual methods of -// the class are, so the vtable and typeinfo symbol must be imported. -// -// PS4-DAG: @_ZTV9FooImport ={{.*}}dllimport -// WI-DAG: @_ZTV9FooImport = linkonce_odr dso_local unnamed_addr constant { -// PS4-DAG: @_ZTI9FooImport ={{.*}}dllimport -// WI-DAG: @_ZTI9FooImport = linkonce_odr dso_local constant { - - -struct FooImport -{ - virtual void getId() const {} - __declspec(dllimport) virtual void Bump(); - __declspec(dllimport) virtual void Decrement(); -}; - -// 'FooImport::Bump()' is the key function, so the vtable and typeinfo symbol -// of 'FooImport' will be defined in the TU that contains the definition of -// 'Bump()' (and they must be exported from there). Here, we will reference -// the vtable and typeinfo symbol, so we must also import them. -void importTest() -{ - typeid(FooImport).name(); -} - -/////////////////////////////////////////////////////////////////// - -// Case (b) -- Export Aspect -// The class as a whole is not exported, but all non-inline virtual methods of -// the class are, so the vtable and typeinfo symbol must be exported. -// -// PS4-DAG: @_ZTV9FooExport ={{.*}}dllexport -// WI-DAG: @_ZTV9FooExport = dso_local unnamed_addr constant { -// PS4-DAG: @_ZTI9FooExport ={{.*}}dllexport -// WI-DAG: @_ZTI9FooExport = dso_local constant { -struct FooExport -{ - virtual void getId() const {} - __declspec(dllexport) virtual void Bump(); - __declspec(dllexport) virtual void Decrement(); -}; - -// This is the key function of the class 'FooExport', so the vtable and -// typeinfo symbol of 'FooExport' will be defined in this TU, and so they must -// be exported from this TU. -void FooExport::Bump() -{ - FooImport f; - typeid(FooExport).name(); -} - -/////////////////////////////////////////////////////////////////// - -// The tests below verify that the associated vtable and typeinfo symbols are -// not imported/exported. These are the converse of case (b). -// -// Note that ultimately, if the module doing the importing calls a constructor -// of the class with the vtable, or makes a reference to the typeinfo symbol of -// the class, then this will result in an unresolved reference (to the vtable -// or typeinfo symbol) when linking the importing module, and thus a link-time -// failure. -// -// Note that with the Microsoft toolchain there will also be a link-time -// failure when linking the module doing the importing. With the Microsoft -// toolchain, it will be an unresolved reference to the method 'Decrement()' -// of the approriate class, rather than to the vtable or typeinfo symbol of -// the class, because Microsoft defines the vtable and typeinfo symbol (weakly) -// everywhere they are used. - -// Converse of case (b) -- Import Aspect -// The class as a whole is not imported, and not all non-inline virtual methods -// are imported, so the vtable and typeinfo symbol are not to be imported. -// -// CHECK-PS4: @_ZTV11FooNoImport = external dso_local unnamed_addr constant { -// CHECK-WI: @_ZTV11FooNoImport = linkonce_odr dso_local unnamed_addr constant { -// CHECK-PS4: @_ZTI11FooNoImport = external dso_local constant ptr{{$}} -// CHECK-WI: @_ZTI11FooNoImport = linkonce_odr dso_local constant { -struct FooNoImport -{ - virtual void getId() const {} - __declspec(dllimport) virtual void Bump(); - virtual void Decrement(); // Not imported. - int mCounter; -}; - -void importNegativeTest() -{ - FooNoImport f; - typeid(FooNoImport).name(); -} - -/////////////////////////////////////////////////////////////////// - -// Converse of case (b) -- Export Aspect -// The class as a whole is not exported, and not all non-inline virtual methods -// are exported, so the vtable and typeinfo symbol are not to be exported. -// -// SCEI_PS4-DAG: @_ZTV11FooNoImport = external unnamed_addr constant { -// SCEI_WI-DAG: @_ZTV11FooNoExport = dso_local unnamed_addr constant { - -// WI-DAG: @_ZTV11FooNoExport = dso_local unnamed_addr constant { -// SCEI_PS4-DAG: @_ZTI11FooNoExport = constant { -// SCEI_WI-DAG: @_ZTI11FooNoExport = dso_local constant { -// WI-DAG: @_ZTI11FooNoExport = dso_local constant { -struct FooNoExport -{ - virtual void getId() const {} - __declspec(dllexport) virtual void Bump(); - virtual void Decrement(); // Not exported. - int mCounter; -}; - -void FooNoExport::Bump() -{ - typeid(FooNoExport).name(); -} diff --git a/clang/test/CodeGenCXX/weak-external.cpp b/clang/test/CodeGenCXX/weak-external.cpp index 5eb262cdbead0..e30d4defd455a 100644 --- a/clang/test/CodeGenCXX/weak-external.cpp +++ b/clang/test/CodeGenCXX/weak-external.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple %itanium_abi_triple %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s // PR4262 // CHECK-NOT: _ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag diff --git a/clang/test/CodeGenCoroutines/coro-aligned-alloc-2.cpp b/clang/test/CodeGenCoroutines/coro-aligned-alloc-2.cpp index 21c2e45b890f3..bfa124bb4dc43 100644 --- a/clang/test/CodeGenCoroutines/coro-aligned-alloc-2.cpp +++ b/clang/test/CodeGenCoroutines/coro-aligned-alloc-2.cpp @@ -1,9 +1,7 @@ // Tests that the combination of -fcoro-aligned-allocation and -fsized-deallocation works well. // Test the compiler will chose sized deallocation correctly. -// This is only enabled with `-fsized-deallocation` which is off by default. // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \ // RUN: -fcoro-aligned-allocation -emit-llvm %s -o - -disable-llvm-passes \ -// RUN: -fsized-deallocation \ // RUN: | FileCheck %s #include "Inputs/coroutine.h" diff --git a/clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp b/clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp index 8019926b730c0..156fa64f454ca 100644 --- a/clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp +++ b/clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp @@ -26,8 +26,9 @@ struct task { // CHECK: %[[aligned_new:.+]] = call{{.*}}@_ZnwmSt11align_val_t({{.*}}%[[coro_size]],{{.*}}%[[coro_align]]) // CHECK: coro.free: +// CHECK: %[[coro_size_for_free:.+]] = call{{.*}}@llvm.coro.size // CHECK: %[[coro_align_for_free:.+]] = call{{.*}}@llvm.coro.align -// CHECK: call void @_ZdlPvSt11align_val_t({{.*}}[[coro_align_for_free]] +// CHECK: call void @_ZdlPvmSt11align_val_t({{.*}}%[[coro_size_for_free]],{{.*}}%[[coro_align_for_free]]) task f() { co_return 43; @@ -58,8 +59,9 @@ void *operator new(std::size_t, std::align_val_t, std::nothrow_t) noexcept; // CHECK: %[[aligned_new:.+]] = call{{.*}}@_ZnwmSt11align_val_tSt9nothrow_t({{.*}}%[[coro_size]],{{.*}}%[[coro_align]]) // CHECK: coro.free: +// CHECK: %[[coro_size_for_free:.+]] = call{{.*}}@llvm.coro.size // CHECK: %[[coro_align_for_free:.+]] = call{{.*}}@llvm.coro.align -// CHECK: call void @_ZdlPvSt11align_val_t({{.*}}[[coro_align_for_free]] +// CHECK: call void @_ZdlPvmSt11align_val_t({{.*}}%[[coro_size_for_free]],{{.*}}%[[coro_align_for_free]]) task2 f2() { co_return 43; diff --git a/clang/test/CodeGenCoroutines/coro-alloc.cpp b/clang/test/CodeGenCoroutines/coro-alloc.cpp index d026a0d7df227..7b3be7e0b7f98 100644 --- a/clang/test/CodeGenCoroutines/coro-alloc.cpp +++ b/clang/test/CodeGenCoroutines/coro-alloc.cpp @@ -70,7 +70,8 @@ extern "C" void f0(global_new_delete_tag) { // CHECK: br i1 %[[NeedDealloc]], label %[[FreeBB:.+]], label %[[Afterwards:.+]] // CHECK: [[FreeBB]]: - // CHECK: call void @_ZdlPv(ptr noundef %[[MEM]]) + // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() + // CHECK: call void @_ZdlPvm(ptr noundef %[[MEM]], i64 noundef %[[SIZE]]) // CHECK: br label %[[Afterwards]] // CHECK: [[Afterwards]]: @@ -99,7 +100,8 @@ extern "C" void f1(promise_new_tag ) { // CHECK: %[[FRAME:.+]] = call ptr @llvm.coro.begin( // CHECK: %[[MEM:.+]] = call ptr @llvm.coro.free(token %[[ID]], ptr %[[FRAME]]) - // CHECK: call void @_ZdlPv(ptr noundef %[[MEM]]) + // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() + // CHECK: call void @_ZdlPvm(ptr noundef %[[MEM]], i64 noundef %[[SIZE]]) co_return; } diff --git a/clang/test/CodeGenCoroutines/coro-cleanup.cpp b/clang/test/CodeGenCoroutines/coro-cleanup.cpp index 98f150758e2d1..4e77ac25af1bf 100644 --- a/clang/test/CodeGenCoroutines/coro-cleanup.cpp +++ b/clang/test/CodeGenCoroutines/coro-cleanup.cpp @@ -84,11 +84,13 @@ void f() { // CHECK: [[Cleanup]]: // CHECK: call void @_ZNSt16coroutine_traitsIJvEE12promise_typeD1Ev( // CHECK: %[[Mem0:.+]] = call ptr @llvm.coro.free( - // CHECK: call void @_ZdlPv(ptr noundef %[[Mem0]] + // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() + // CHECK: call void @_ZdlPvm(ptr noundef %[[Mem0]], i64 noundef %[[SIZE]]) // CHECK: [[Dealloc]]: // THROWEND: %[[Mem:.+]] = call ptr @llvm.coro.free( - // THROWEND: call void @_ZdlPv(ptr noundef %[[Mem]]) + // THROWEND: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() + // THROWEND: call void @_ZdlPvm(ptr noundef %[[Mem]], i64 noundef %[[SIZE]]) co_return; } diff --git a/clang/test/CodeGenCoroutines/coro-dealloc.cpp b/clang/test/CodeGenCoroutines/coro-dealloc.cpp index 3cdba6cafdc0b..5a699ac9b5851 100644 --- a/clang/test/CodeGenCoroutines/coro-dealloc.cpp +++ b/clang/test/CodeGenCoroutines/coro-dealloc.cpp @@ -1,6 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \ // RUN: -emit-llvm %s -o - -disable-llvm-passes \ -// RUN: -fsized-deallocation \ // RUN: | FileCheck %s #include "Inputs/coroutine.h" @@ -21,7 +20,6 @@ struct task { }; // Test the compiler will chose sized deallocation correctly. -// This is only enabled with `-fsized-deallocation` which is off by default. void operator delete(void *ptr, std::size_t size) noexcept; // CHECK: define{{.*}}@_Z1fv diff --git a/clang/test/CodeGenCoroutines/coro-gro.cpp b/clang/test/CodeGenCoroutines/coro-gro.cpp index d4c3ff589e340..b62134317cef2 100644 --- a/clang/test/CodeGenCoroutines/coro-gro.cpp +++ b/clang/test/CodeGenCoroutines/coro-gro.cpp @@ -51,7 +51,8 @@ int f() { // CHECK: call void @_ZNSt16coroutine_traitsIiJEE12promise_typeD1Ev( // CHECK: %[[Mem:.+]] = call ptr @llvm.coro.free( - // CHECK: call void @_ZdlPv(ptr noundef %[[Mem]]) + // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64() + // CHECK: call void @_ZdlPvm(ptr noundef %[[Mem]], i64 noundef %[[SIZE]]) // Initialize retval from Gro and destroy Gro // Note this also tests delaying initialization when Gro and function return diff --git a/clang/test/CodeGenCoroutines/pr56919.cpp b/clang/test/CodeGenCoroutines/pr56919.cpp index c7de08ef72d7f..baa8c27ce6649 100644 --- a/clang/test/CodeGenCoroutines/pr56919.cpp +++ b/clang/test/CodeGenCoroutines/pr56919.cpp @@ -111,12 +111,15 @@ Task Bar() { co_await Baz(); } // CHECK: _Z3Quxv.destroy:{{.*}} // CHECK-NEXT: # -// CHECK-NEXT: jmp _ZdlPv +// CHECK-NEXT: movl $40, %esi +// CHECK-NEXT: jmp _ZdlPvm@PLT // CHECK: _Z3Bazv.destroy:{{.*}} // CHECK-NEXT: # -// CHECK-NEXT: jmp _ZdlPv +// CHECK-NEXT: movl $80, %esi +// CHECK-NEXT: jmp _ZdlPvm // CHECK: _Z3Barv.destroy:{{.*}} // CHECK-NEXT: # -// CHECK-NEXT: jmp _ZdlPv +// CHECK-NEXT: movl $120, %esi +// CHECK-NEXT: jmp _ZdlPvm diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx940.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx940.cl new file mode 100644 index 0000000000000..fc5649d8a41f7 --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx940.cl @@ -0,0 +1,52 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -cl-std=CL2.0 -O0 -triple amdgcn-unknown-unknown -target-cpu gfx940 -emit-llvm -o - %s | FileCheck %s +// REQUIRES: amdgpu-registered-target + +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; + +// CHECK-LABEL: @test_global_load_lds_u32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[DST_ADDR:%.*]] = alloca ptr addrspace(3), align 4, addrspace(5) +// CHECK-NEXT: store ptr addrspace(1) [[SRC:%.*]], ptr addrspace(5) [[SRC_ADDR]], align 8 +// CHECK-NEXT: store ptr addrspace(3) [[DST:%.*]], ptr addrspace(5) [[DST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[SRC_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(3), ptr addrspace(5) [[DST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.amdgcn.global.load.lds(ptr addrspace(1) [[TMP0]], ptr addrspace(3) [[TMP1]], i32 4, i32 0, i32 0) +// CHECK-NEXT: ret void +// +void test_global_load_lds_u32(global u32* src, local u32 *dst) { + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/4, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_global_load_lds_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[DST_ADDR:%.*]] = alloca ptr addrspace(3), align 4, addrspace(5) +// CHECK-NEXT: store ptr addrspace(1) [[SRC:%.*]], ptr addrspace(5) [[SRC_ADDR]], align 8 +// CHECK-NEXT: store ptr addrspace(3) [[DST:%.*]], ptr addrspace(5) [[DST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[SRC_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(3), ptr addrspace(5) [[DST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.amdgcn.global.load.lds(ptr addrspace(1) [[TMP0]], ptr addrspace(3) [[TMP1]], i32 2, i32 0, i32 0) +// CHECK-NEXT: ret void +// +void test_global_load_lds_u16(global u16* src, local u16 *dst) { + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/2, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_global_load_lds_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[DST_ADDR:%.*]] = alloca ptr addrspace(3), align 4, addrspace(5) +// CHECK-NEXT: store ptr addrspace(1) [[SRC:%.*]], ptr addrspace(5) [[SRC_ADDR]], align 8 +// CHECK-NEXT: store ptr addrspace(3) [[DST:%.*]], ptr addrspace(5) [[DST_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[SRC_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(3), ptr addrspace(5) [[DST_ADDR]], align 4 +// CHECK-NEXT: call void @llvm.amdgcn.global.load.lds(ptr addrspace(1) [[TMP0]], ptr addrspace(3) [[TMP1]], i32 1, i32 0, i32 0) +// CHECK-NEXT: ret void +// +void test_global_load_lds_u8(global u8* src, local u8 *dst) { + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/1, /*offset=*/0, /*aux=*/0); +} diff --git a/clang/test/CoverageMapping/builtinmacro.c b/clang/test/CoverageMapping/builtinmacro.c index abcdc191523a5..5d5a176aa7d87 100644 --- a/clang/test/CoverageMapping/builtinmacro.c +++ b/clang/test/CoverageMapping/builtinmacro.c @@ -4,7 +4,7 @@ // CHECK: filename const char *filename (const char *name) { // CHECK-NEXT: File 0, [[@LINE]]:41 -> [[@LINE+3]]:2 = #0 - static const char this_file[] = __FILE__; + static const char this_file[] = __FILE__; // CHECK-NEXT: File 0, [[@LINE]]:35 -> [[@LINE]]:35 = #0 return this_file; } diff --git a/clang/test/CoverageMapping/macros.c b/clang/test/CoverageMapping/macros.c index 6bd3be434139a..fcf21170ef135 100644 --- a/clang/test/CoverageMapping/macros.c +++ b/clang/test/CoverageMapping/macros.c @@ -80,12 +80,14 @@ void func7(void) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+6]]:2 = #0 int kk,ll; // CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:8 = #0 if (k) // CHECK-NEXT: Branch,File 0, [[@LINE]]:7 -> [[@LINE]]:8 = #1 m(k); // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:9 -> [[@LINE]]:5 = #1 - else // CHECK-NEXT: Expansion,File 0, [[@LINE-1]]:5 -> [[@LINE-1]]:6 = #0 + else // CHECK-NEXT: Expansion,File 0, [[@LINE-1]]:5 -> [[@LINE-1]]:6 = #1 l = m(l); // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:7 -> [[@LINE]]:5 = (#0 - #1) } // CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE-1]]:10 = (#0 - #1) // CHECK-NEXT: Expansion,File 0, [[@LINE-2]]:9 -> [[@LINE-2]]:10 = (#0 - #1) - // CHECK-NEXT: File 1, [[@LINE-9]]:14 -> [[@LINE-9]]:18 = #0 - // CHECK-NEXT: File 2, [[@LINE-10]]:14 -> [[@LINE-10]]:15 = (#0 - #1) + // CHECK-NEXT: File 1, [[@LINE-9]]:14 -> [[@LINE-9]]:17 = #1 + // CHECK-NEXT: File 1, [[@LINE-10]]:14 -> [[@LINE-10]]:18 = #0 + // CHECK-NEXT: File 2, [[@LINE-11]]:14 -> [[@LINE-11]]:17 = (#0 - #1) + // CHECK-NEXT: File 2, [[@LINE-12]]:14 -> [[@LINE-12]]:15 = (#0 - #1) int main(int argc, const char *argv[]) { func(); diff --git a/clang/test/CoverageMapping/mcdc-scratch-space.c b/clang/test/CoverageMapping/mcdc-scratch-space.c new file mode 100644 index 0000000000000..2b5b12d9dcad6 --- /dev/null +++ b/clang/test/CoverageMapping/mcdc-scratch-space.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c99 -fcoverage-mcdc -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s | FileCheck %s + +// CHECK: builtin_macro0: +int builtin_macro0(int a) { + // CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:15 = M:0, C:2 + return (__LINE__ // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:11 = 0, 0 [1,2,0] + && a); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:15 = #2, (#1 - #2) [2,0,0] +} + +// CHECK: builtin_macro1: +int builtin_macro1(int a) { + // CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:22 = M:0, C:2 + return (a // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = (#0 - #1), #1 [1,0,2] + || __LINE__); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:14 = 0, 0 [2,0,0] +} + +#define PRE(x) pre_##x + +// CHECK: pre0: +int pre0(int pre_a, int b_post) { + // CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:20 = M:0, C:2 + // CHECK: Expansion,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:14 = #0 (Expanded file = 1) + return (PRE(a) + && b_post); + // CHECK: Branch,File 0, [[@LINE-1]]:14 -> [[@LINE-1]]:20 = #2, (#1 - #2) [2,0,0] + // CHECK: Branch,File 1, [[@LINE-9]]:16 -> [[@LINE-9]]:22 = #1, (#0 - #1) [1,2,0] +} + +#define pre_foo pre_a + +// CHECK: pre1: +int pre1(int pre_a, int b_post) { + // CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:20 = M:0, C:2 + // CHECK: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:14 = #0 (Expanded file = 1) + // CHECK: Branch,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = #2, (#1 - #2) [2,0,0] + return (PRE(foo) + && b_post); + // CHECK: Expansion,File 1, 17:16 -> 17:20 = #0 (Expanded file = 2) + // CHECK: Branch,File 2, 29:17 -> 29:22 = #1, (#0 - #1) [1,2,0] +} + +#define POST(x) x##_post + +// CHECK: post0: +int post0(int pre_a, int b_post) { + // CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:18 = M:0, C:2 + // CHECK: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:16 = (#0 - #1), #1 [1,0,2] + return (pre_a + || POST(b)); + // CHECK: Expansion,File 0, [[@LINE-1]]:14 -> [[@LINE-1]]:18 = #1 (Expanded file = 1) + // CHECK: Branch,File 1, [[@LINE-9]]:17 -> [[@LINE-9]]:20 = (#1 - #2), #2 [2,0,0] +} + +#define bar_post b_post + +// CHECK: post1: +int post1(int pre_a, int b_post) { + // CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:18 = M:0, C:2 + // CHECK: Branch,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = (#0 - #1), #1 [1,0,2] + // CHECK: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:18 = 0 (Expanded file = 1) + return (pre_a + || POST(bar)); + // CHECK: Expansion,File 1, 42:17 -> 42:18 = #1 (Expanded file = 2) + // CHECK: Branch,File 2, 54:18 -> 54:24 = (#1 - #2), #2 [2,0,0] +} diff --git a/clang/test/CoverageMapping/templates.cpp b/clang/test/CoverageMapping/templates.cpp index 143e566a33cb8..7e7f2208f1145 100644 --- a/clang/test/CoverageMapping/templates.cpp +++ b/clang/test/CoverageMapping/templates.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name templates.cpp %s | FileCheck %s +// RUN: %clang_cc1 -std=c++20 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name templates.cpp %s | FileCheck %s template void unused(T x) { @@ -30,5 +30,6 @@ namespace structural_value_crash { void test() { tpl_fn(); + tpl_fn<&arr[1]>(); } } diff --git a/clang/test/Driver/Ofast.c b/clang/test/Driver/Ofast.c index 1f9fc78ec1ef8..8b7f2217eca2f 100644 --- a/clang/test/Driver/Ofast.c +++ b/clang/test/Driver/Ofast.c @@ -3,7 +3,9 @@ // RUN: %clang -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s // RUN: %clang -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s // RUN: %clang -fno-vectorize -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s -// RUN: %clang -Ofast -O2 -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 %s +// RUN: %clang -Ofast -O2 -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-O2 \ +// RUN: %if target={{.*-windows-msvc.*}} %{ --check-prefix=CHECK-OFAST-O2-ALIASING-MSVC %} \ +// RUN: %else %{ --check-prefix=CHECK-OFAST-O2-ALIASING %} %s // RUN: %clang -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s // RUN: %clang -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s // RUN: %clang -Ofast -fno-vectorize -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-VECTORIZE %s @@ -15,7 +17,8 @@ // CHECK-OFAST: -vectorize-loops // CHECK-OFAST-O2: -cc1 -// CHECK-OFAST-O2-NOT: -relaxed-aliasing +// CHECK-OFAST-O2-ALIASING-NOT: -relaxed-aliasing +// CHECK-OFAST-O2-ALIASING-MSVC: -relaxed-aliasing // CHECK-OFAST-O2-NOT: -ffast-math // CHECK-OFAST-O2-NOT: -Ofast // CHECK-OFAST-O2: -vectorize-loops diff --git a/clang/test/Driver/aarch64-v95a.c b/clang/test/Driver/aarch64-v95a.c index 1037da65c8cb5..62878f2127626 100644 --- a/clang/test/Driver/aarch64-v95a.c +++ b/clang/test/Driver/aarch64-v95a.c @@ -6,7 +6,7 @@ // RUN: %clang -target aarch64 -mlittle-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s // RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s // RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A %s -// GENERICV95A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a" +// GENERICV95A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+cpa"{{.*}} "-target-feature" "+faminmax"{{.*}} "-target-feature" "+lut" // RUN: %clang -target aarch64_be -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s // RUN: %clang -target aarch64_be -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s @@ -14,14 +14,10 @@ // RUN: %clang -target aarch64 -mbig-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.5-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV95A-BE %s -// GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a" +// GENERICV95A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+cpa"{{.*}} "-target-feature" "+faminmax"{{.*}} "-target-feature" "+lut" // ===== Features supported on aarch64 ===== -// RUN: %clang -target aarch64 -march=armv9.5a+cpa -### -c %s 2>&1 | FileCheck -check-prefix=V95A-CPA %s -// RUN: %clang -target aarch64 -march=armv9.5-a+cpa -### -c %s 2>&1 | FileCheck -check-prefix=V95A-CPA %s -// V95A-CPA: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+cpa" - // RUN: %clang -target aarch64 -march=armv9.5a+pauth-lr -### -c %s 2>&1 | FileCheck -check-prefix=V95A-PAUTHLR %s // RUN: %clang -target aarch64 -march=armv9.5-a+pauth-lr -### -c %s 2>&1 | FileCheck -check-prefix=V95A-PAUTHLR %s // V95A-PAUTHLR: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.5a"{{.*}} "-target-feature" "+pauth-lr" diff --git a/clang/test/Driver/android-unversioned-fallback-warning.cpp b/clang/test/Driver/android-unversioned-fallback-warning.cpp index 62a951d14effa..da666cc4d9faf 100644 --- a/clang/test/Driver/android-unversioned-fallback-warning.cpp +++ b/clang/test/Driver/android-unversioned-fallback-warning.cpp @@ -14,14 +14,14 @@ // RUN: %clang --target=aarch64-none-linux-android -ccc-install-dir %t/bin \ // RUN: -resource-dir %t/resource -### -c %s 2>&1 | \ // RUN: FileCheck --check-prefix=NO-WARNING %s -// NO-WARNING-NOT: Using unversioned Android target directory +// NO-WARNING-NOT: using unversioned Android target directory // RUN: %clang --target=aarch64-none-linux-android21 -ccc-install-dir %t/bin \ // RUN: -resource-dir %t/resource -### -c %s 2>&1 | \ // RUN: FileCheck --check-prefix=ANDROID21 -DDIR=%t -DSEP=%{fs-sep} %s -// ANDROID21-DAG: Using unversioned Android target directory [[DIR]]/bin[[SEP]]..[[SEP]]include[[SEP]]aarch64-none-linux-android -// ANDROID21-DAG: Using unversioned Android target directory [[DIR]]/bin[[SEP]]..[[SEP]]lib[[SEP]]aarch64-none-linux-android -// ANDROID21-DAG: Using unversioned Android target directory [[DIR]]/resource[[SEP]]lib[[SEP]]aarch64-none-linux-android +// ANDROID21-DAG: using unversioned Android target directory [[DIR]]/bin[[SEP]]..[[SEP]]include[[SEP]]aarch64-none-linux-android +// ANDROID21-DAG: using unversioned Android target directory [[DIR]]/bin[[SEP]]..[[SEP]]lib[[SEP]]aarch64-none-linux-android +// ANDROID21-DAG: using unversioned Android target directory [[DIR]]/resource[[SEP]]lib[[SEP]]aarch64-none-linux-android // 23 or newer should use the versioned directory // RUN: %clang --target=aarch64-none-linux-android23 -ccc-install-dir %t/bin \ diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 75f49deca0653..733f243d3c69b 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -740,9 +740,10 @@ // NOCLANG-SAME: "-vectorize-slp" // NOCLANG-NOT: "--dependent-lib=msvcrt" -// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep -### -- %s 2>&1 | FileCheck -check-prefix=CLANG %s +// RUN: %clang_cl -O2 -MD /clang:-fno-slp-vectorize /clang:-MD /clang:-MF /clang:my_dependency_file.dep /c /Fo%/t/cl-options.obj -### -- %s 2>&1 | FileCheck -DPREFIX=%/t -check-prefix=CLANG %s // CLANG: "--dependent-lib=msvcrt" // CLANG-SAME: "-dependency-file" "my_dependency_file.dep" +// CLANG-SAME: "-MT" "[[PREFIX]]/cl-options.obj" // CLANG-NOT: "--dependent-lib=libcmt" // CLANG-NOT: "-vectorize-slp" diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c index 716b02f02a15e..51b16f0ce3546 100644 --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -69,10 +69,7 @@ // RUN: %clang_cl -m32 -arch:avx2 --target=i386-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx2 %s // avx2: invalid /arch: argument -// RUN: %clang_cl -m32 -arch:AVX512F --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify=KNL1 -DTEST_32_ARCH_AVX512F -- %s -// KNL1-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// KNL1-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// KNL1-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} +// RUN: %clang_cl -m32 -arch:AVX512F --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_32_ARCH_AVX512F -- %s #if defined(TEST_32_ARCH_AVX512F) #if _M_IX86_FP != 2 || !__AVX__ || !__AVX2__ || !__AVX512F__ || __AVX512BW__ #error fail @@ -112,10 +109,7 @@ // RUN: %clang_cl -m64 -arch:avx2 --target=x86_64-pc-windows -### -- 2>&1 %s | FileCheck -check-prefix=avx264 %s // avx264: invalid /arch: argument -// RUN: %clang_cl -m64 -arch:AVX512F --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify=KNL2 -DTEST_64_ARCH_AVX512F -- %s -// KNL2-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// KNL2-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// KNL2-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} +// RUN: %clang_cl -m64 -arch:AVX512F --target=i386-pc-windows /c /Fo%t.obj -Xclang -verify -DTEST_64_ARCH_AVX512F -- %s #if defined(TEST_64_ARCH_AVX512F) #if _M_IX86_FP || !__AVX__ || !__AVX2__ || !__AVX512F__ || __AVX512BW__ #error fail diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 472d0725a7934..d69cd199ac61d 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -623,3 +623,9 @@ // RUN: %clang -### --target=aarch64-windows-msvc -fno-ms-volatile %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MS-VOLATILE %s // CHECK-MS-VOLATILE: -fms-volatile // CHECK-NO-MS-VOLATILE-NOT: -fms-volatile + +// RUN: %clang -### --target=x86_64-pc-windows-msvc %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-ALIASING %s +// RUN: %clang -### --target=x86_64-pc-windows-msvc -fstrict-aliasing %s 2>&1 | FileCheck -check-prefix=CHECK-STRICT-ALIASING %s +// RUN: %clang -### --target=x86_64-pc-windows-msvc -fno-strict-aliasing %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-ALIASING %s +// CHECK-STRICT-ALIASING-NOT: -relaxed-aliasing +// CHECK-NO-STRICT-ALIASING: -relaxed-aliasing diff --git a/clang/test/Driver/cuda-cross-compiling.c b/clang/test/Driver/cuda-cross-compiling.c index a1719a6fbe042..203bc063a0106 100644 --- a/clang/test/Driver/cuda-cross-compiling.c +++ b/clang/test/Driver/cuda-cross-compiling.c @@ -83,8 +83,8 @@ // RUN: not %clang -target nvptx64-nvidia-cuda -march=generic %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=MISSING %s -// MISSING: error: Must pass in an explicit nvptx64 gpu architecture to 'ptxas' -// MISSING: error: Must pass in an explicit nvptx64 gpu architecture to 'nvlink' +// MISSING: error: must pass in an explicit nvptx64 gpu architecture to 'ptxas' +// MISSING: error: must pass in an explicit nvptx64 gpu architecture to 'nvlink' // RUN: %clang -target nvptx64-nvidia-cuda -flto -c %s -### 2>&1 \ // RUN: | FileCheck -check-prefix=GENERIC %s diff --git a/clang/test/Driver/dxc_dxv_path.hlsl b/clang/test/Driver/dxc_dxv_path.hlsl index 4845de11d5b00..db2c87063ac31 100644 --- a/clang/test/Driver/dxc_dxv_path.hlsl +++ b/clang/test/Driver/dxc_dxv_path.hlsl @@ -1,7 +1,7 @@ // RUN: %clang_dxc -I test -Tlib_6_3 -### %s 2>&1 | FileCheck %s // Make sure report warning. -// CHECK:dxv not found. +// CHECK:dxv not found // RUN: echo "dxv" > %T/dxv && chmod 754 %T/dxv && %clang_dxc --dxv-path=%T %s -Tlib_6_3 -### 2>&1 | FileCheck %s --check-prefix=DXV_PATH // DXV_PATH:dxv{{(.exe)?}}" "-" "-o" "-" diff --git a/clang/test/Driver/fast-math.c b/clang/test/Driver/fast-math.c index 274f1f22ea5e9..ffd081948914d 100644 --- a/clang/test/Driver/fast-math.c +++ b/clang/test/Driver/fast-math.c @@ -67,31 +67,31 @@ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s // // Target defaults for -fmath-errno (reusing the above checks). -// RUN: %clang -### -target i686-unknown-linux -c %s 2>&1 \ +// RUN: %clang -### --target=i686-unknown-linux -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,ERRNO %s // RUN: %clang -### -target i686-apple-darwin -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-unknown-freebsd -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-unknown-freebsd -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-unknown-netbsd -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-unknown-netbsd -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-unknown-openbsd -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-unknown-openbsd -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s // RUN: %clang -### --target=x86_64-unknown-haiku -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-unknown-dragonfly -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-unknown-dragonfly -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-fuchsia -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-fuchsia -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-linux-android -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-linux-android -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target x86_64-linux-musl -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64-linux-musl -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s // RUN: %clang -### --target=amdgcn-amd-amdhsa -nogpuinc -nogpulib -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target amdgcn-amd-amdpal -c %s 2>&1 \ +// RUN: %clang -### --target=amdgcn-amd-amdpal -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s -// RUN: %clang -### -target amdgcn-mesa-mesa3d -c %s 2>&1 \ +// RUN: %clang -### --target=amdgcn-mesa-mesa3d -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s // // Check that -ffast-math disables -fmath-errno, and -fno-fast-math merely @@ -103,9 +103,9 @@ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s // RUN: %clang -### -ffast-math -fmath-errno -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,ERRNO %s -// RUN: %clang -### -target i686-unknown-linux -fno-fast-math -c %s 2>&1 \ +// RUN: %clang -### --target=i686-unknown-linux -fno-fast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,ERRNO %s -// RUN: %clang -### -target i686-unknown-linux -fno-math-errno -fno-fast-math -c %s 2>&1 \ +// RUN: %clang -### --target=i686-unknown-linux -fno-math-errno -fno-fast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,ERRNO %s // RUN: %clang -### -target i686-apple-darwin -fno-fast-math -c %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK,NO-ERRNO %s diff --git a/clang/test/Driver/fat-archive-unbundle-ext.c b/clang/test/Driver/fat-archive-unbundle-ext.c index e98b872f0c0c3..e797acccf02b4 100644 --- a/clang/test/Driver/fat-archive-unbundle-ext.c +++ b/clang/test/Driver/fat-archive-unbundle-ext.c @@ -2,7 +2,7 @@ // UNSUPPORTED: target={{.*-windows.*}}, target={{.*}}-macosx{{.*}}, target={{.*-darwin.*}}, target={{.*}}-aix{{.*}} // Generate dummy fat object -// RUN: %clang -O0 -target %itanium_abi_triple %s -c -o %t.host.o +// RUN: %clang -O0 --target=%itanium_abi_triple %s -c -o %t.host.o // RUN: echo 'Content of device file' > %t.tgt.o // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-%itanium_abi_triple -input=%t.host.o -input=%t.tgt.o -output=%t.fat.obj diff --git a/clang/test/Driver/fatal-warnings.c b/clang/test/Driver/fatal-warnings.c index 6239b25e8917b..12c239cf12083 100644 --- a/clang/test/Driver/fatal-warnings.c +++ b/clang/test/Driver/fatal-warnings.c @@ -1,5 +1,5 @@ -// RUN: %clang -### %s -c -o tmp.o -target i686-pc-linux-gnu -integrated-as -Wa,--fatal-warnings 2>&1 | FileCheck %s -// RUN: not %clang %s -c -o %t.o -target i686-pc-linux-gnu -integrated-as -Wa,--fatal-warnings 2>&1 %t.log +// RUN: %clang -### %s -c -o tmp.o --target=i686-pc-linux-gnu -integrated-as -Wa,--fatal-warnings 2>&1 | FileCheck %s +// RUN: not %clang %s -c -o %t.o --target=i686-pc-linux-gnu -integrated-as -Wa,--fatal-warnings 2>&1 %t.log // FileCheck --check-prefix=CHECK-AS %s -input-file %t.log // CHECK: "-cc1" {{.*}} "-massembler-fatal-warnings" diff --git a/clang/test/Driver/fbinutils-version.c b/clang/test/Driver/fbinutils-version.c index 56a49ed2540fa..14b44b4d9dd07 100644 --- a/clang/test/Driver/fbinutils-version.c +++ b/clang/test/Driver/fbinutils-version.c @@ -1,29 +1,29 @@ -// RUN: %clang -### -c -target x86_64-linux %s -fbinutils-version=none 2>&1 | FileCheck %s --check-prefix=NONE +// RUN: %clang -### -c --target=x86_64-linux %s -fbinutils-version=none 2>&1 | FileCheck %s --check-prefix=NONE // NONE: "-fbinutils-version=none" -// RUN: %clang -### -c -target aarch64-linux %s -fbinutils-version=2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %clang -### -c --target=aarch64-linux %s -fbinutils-version=2 2>&1 | FileCheck %s --check-prefix=CHECK2 // CHECK2: "-fbinutils-version=2" -// RUN: %clang -### -c -target aarch64-linux %s -fbinutils-version=2.35 2>&1 | FileCheck %s --check-prefix=CHECK2_35 +// RUN: %clang -### -c --target=aarch64-linux %s -fbinutils-version=2.35 2>&1 | FileCheck %s --check-prefix=CHECK2_35 // CHECK2_35: "-fbinutils-version=2.35" /// Disallow -fbinutils-version=0 because we use $major==0 to indicate the MC /// default in the backend. -// RUN: not %clang -c -target x86_64-linux %s -fbinutils-version=0 2>&1 | FileCheck %s --check-prefix=ERR0 +// RUN: not %clang -c --target=x86_64-linux %s -fbinutils-version=0 2>&1 | FileCheck %s --check-prefix=ERR0 // ERR0: error: invalid argument '0' to -fbinutils-version= -// RUN: not %clang -c -target x86_64-linux %s -fbinutils-version=nan 2>&1 | FileCheck %s --check-prefix=ERR1 +// RUN: not %clang -c --target=x86_64-linux %s -fbinutils-version=nan 2>&1 | FileCheck %s --check-prefix=ERR1 // ERR1: error: invalid argument 'nan' to -fbinutils-version= -// RUN: not %clang -c -target x86_64-linux %s -fbinutils-version=2. 2>&1 | FileCheck %s --check-prefix=ERR2 +// RUN: not %clang -c --target=x86_64-linux %s -fbinutils-version=2. 2>&1 | FileCheck %s --check-prefix=ERR2 // ERR2: error: invalid argument '2.' to -fbinutils-version= -// RUN: not %clang -c -target x86_64-linux %s -fbinutils-version=3.-14 2>&1 | FileCheck %s --check-prefix=ERR3 +// RUN: not %clang -c --target=x86_64-linux %s -fbinutils-version=3.-14 2>&1 | FileCheck %s --check-prefix=ERR3 // ERR3: error: invalid argument '3.-14' to -fbinutils-version= diff --git a/clang/test/Driver/fdirect-access-external-data.c b/clang/test/Driver/fdirect-access-external-data.c index a6da776e69777..4dfb700d6c450 100644 --- a/clang/test/Driver/fdirect-access-external-data.c +++ b/clang/test/Driver/fdirect-access-external-data.c @@ -1,13 +1,13 @@ /// -fno-pic code defaults to -fdirect-access-external-data. -// RUN: %clang -### -c -target x86_64 %s 2>&1 | FileCheck %s --check-prefix=DEFAULT -// RUN: %clang -### -c -target x86_64 %s -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT -// RUN: %clang -### -c -target x86_64 %s -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=INDIRECT +// RUN: %clang -### -c --target=x86_64 %s 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c --target=x86_64 %s -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c --target=x86_64 %s -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=INDIRECT /// -fpie/-fpic code defaults to -fdirect-access-external-data. -// RUN: %clang -### -c -target x86_64 %s -fpie 2>&1 | FileCheck %s --check-prefix=DEFAULT -// RUN: %clang -### -c -target x86_64 %s -fpie -fno-direct-access-external-data -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT -// RUN: %clang -### -c -target aarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT -// RUN: %clang -### -c -target aarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT +// RUN: %clang -### -c --target=x86_64 %s -fpie 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c --target=x86_64 %s -fpie -fno-direct-access-external-data -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT +// RUN: %clang -### -c --target=aarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang -### -c --target=aarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT /// loongarch* targets default to -fno-direct-access-external-data even for -fno-pic. // RUN: %clang -### -c --target=loongarch64 -fno-pic %s 2>&1 | FileCheck %s --check-prefix=INDIRECT diff --git a/clang/test/Driver/fembed-bitcode.c b/clang/test/Driver/fembed-bitcode.c index 970500525a503..9081314d121cb 100644 --- a/clang/test/Driver/fembed-bitcode.c +++ b/clang/test/Driver/fembed-bitcode.c @@ -1,5 +1,5 @@ // RUN: %clang -target x86_64-apple-macosx -fembed-bitcode=all -c %s -o /dev/null -### 2>&1 \ -// RUN: | FileCheck -check-prefix CHECK-X64 %s +// RUN: | FileCheck --check-prefix=CHECK-X64 %s // CHECK-X64: "-cc1" @@ -7,7 +7,7 @@ // CHECK-X64-NOT: "-fdebug-compilation-dir // RUN: %clang -target armv7-apple-ios -fembed-bitcode=all -c %s -o /dev/null -### 2>&1 \ -// RUN: | FileCheck -check-prefix CHECK-ARM %s +// RUN: | FileCheck --check-prefix=CHECK-ARM %s // CHECK-ARM: "-cc1" @@ -17,7 +17,7 @@ // CHECK-ARM-NOT: "-fdebug-compilation-dir // RUN: %clang -target arm64-apple-ios -fembed-bitcode=all -c %s -o /dev/null -### 2>&1 \ -// RUN: | FileCheck -check-prefix CHECK-AARCH64 %s +// RUN: | FileCheck --check-prefix=CHECK-AARCH64 %s // CHECK-AARCH64: "-cc1" @@ -26,12 +26,12 @@ // CHECK-AARCH64: "darwinpcs" // CHECK-AARCH64-NOT: "-fdebug-compilation-dir -// RUN: %clang -target hexagon-unknown-elf -ffixed-r19 -fembed-bitcode=all -c %s -### 2>&1 \ +// RUN: %clang --target=hexagon-unknown-elf -ffixed-r19 -fembed-bitcode=all -c %s -### 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-HEXAGON %s // CHECK-HEXAGON: "-target-feature" // CHECK-HEXAGON: "+reserved-r19" // -// RUN: %clang -target wasm32-unknown-unknown -fembed-bitcode=all -pthread -c %s -o /dev/null -### 2>&1 \ +// RUN: %clang --target=wasm32-unknown-unknown -fembed-bitcode=all -pthread -c %s -o /dev/null -### 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-WASM %s // CHECK-WASM: "-cc1" diff --git a/clang/test/Driver/fexcess-precision.c b/clang/test/Driver/fexcess-precision.c index 68579b606c9b1..0aa1022f17fdc 100644 --- a/clang/test/Driver/fexcess-precision.c +++ b/clang/test/Driver/fexcess-precision.c @@ -1,19 +1,19 @@ // Note: %s must be preceded by --, otherwise it may be interpreted as a // command-line option, e.g. on Mac where %s is commonly under /Users. -// RUN: %clang -### -target i386 -fexcess-precision=fast -c %s 2>&1 \ +// RUN: %clang -### --target=i386 -fexcess-precision=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang_cl -### -target i386 -fexcess-precision=fast -c -- %s 2>&1 \ +// RUN: %clang_cl -### --target=i386 -fexcess-precision=fast -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang -### -target i386 -fexcess-precision=standard -c %s 2>&1 \ +// RUN: %clang -### --target=i386 -fexcess-precision=standard -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-STD %s -// RUN: %clang_cl -### -target i386 -fexcess-precision=standard -c -- %s 2>&1 \ +// RUN: %clang_cl -### --target=i386 -fexcess-precision=standard -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-STD %s -// RUN: %clang -### -target i386 -fexcess-precision=16 -c %s 2>&1 \ +// RUN: %clang -### --target=i386 -fexcess-precision=16 -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NONE %s -// RUN: %clang_cl -### -target i386 -fexcess-precision=16 -c -- %s 2>&1 \ +// RUN: %clang_cl -### --target=i386 -fexcess-precision=16 -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NONE %s // RUN: not %clang -### --target=i386 -fexcess-precision=none -c %s 2>&1 \ @@ -21,19 +21,19 @@ // RUN: not %clang_cl -### --target=i386 -fexcess-precision=none -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-ERR-NONE %s -// RUN: %clang -### -target x86_64 -fexcess-precision=fast -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64 -fexcess-precision=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang_cl -### -target x86_64 -fexcess-precision=fast -c -- %s 2>&1 \ +// RUN: %clang_cl -### --target=x86_64 -fexcess-precision=fast -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang -### -target x86_64 -fexcess-precision=standard -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64 -fexcess-precision=standard -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-STD %s -// RUN: %clang_cl -### -target x86_64 -fexcess-precision=standard -c \ +// RUN: %clang_cl -### --target=x86_64 -fexcess-precision=standard -c \ // RUN: -- %s 2>&1 | FileCheck --check-prefix=CHECK-STD %s -// RUN: %clang -### -target x86_64 -fexcess-precision=16 -c %s 2>&1 \ +// RUN: %clang -### --target=x86_64 -fexcess-precision=16 -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NONE %s -// RUN: %clang_cl -### -target x86_64 -fexcess-precision=16 -c -- %s 2>&1 \ +// RUN: %clang_cl -### --target=x86_64 -fexcess-precision=16 -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NONE %s // RUN: not %clang -### --target=x86_64 -fexcess-precision=none -c %s 2>&1 \ @@ -41,14 +41,14 @@ // RUN: not %clang_cl -### --target=x86_64 -fexcess-precision=none -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK-ERR-NONE %s -// RUN: %clang -### -target aarch64 -fexcess-precision=fast -c %s 2>&1 \ +// RUN: %clang -### --target=aarch64 -fexcess-precision=fast -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK %s -// RUN: %clang_cl -### -target aarch64 -fexcess-precision=fast -c -- %s 2>&1 \ +// RUN: %clang_cl -### --target=aarch64 -fexcess-precision=fast -c -- %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK %s -// RUN: %clang -### -target aarch64 -fexcess-precision=standard -c %s 2>&1 \ +// RUN: %clang -### --target=aarch64 -fexcess-precision=standard -c %s 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK %s -// RUN: %clang_cl -### -target aarch64 -fexcess-precision=standard -c \ +// RUN: %clang_cl -### --target=aarch64 -fexcess-precision=standard -c \ // RUN: -- %s 2>&1 | FileCheck --check-prefix=CHECK %s // RUN: not %clang -### --target=aarch64 -fexcess-precision=16 -c %s 2>&1 \ diff --git a/clang/test/Driver/fextend-args.c b/clang/test/Driver/fextend-args.c index 7f19f8c5ec487..0b721202a0006 100644 --- a/clang/test/Driver/fextend-args.c +++ b/clang/test/Driver/fextend-args.c @@ -5,7 +5,7 @@ // RUN: | FileCheck -check-prefix=CHECK-64 %s // Unsupported target -// RUN: not %clang -target aarch64-unknown-windows-msvc -fextend-arguments=32 %s 2>&1 \ +// RUN: not %clang --target=aarch64-unknown-windows-msvc -fextend-arguments=32 %s 2>&1 \ // RUN: | FileCheck -check-prefix=UNSUPPORTED-TARGET %s // Invalid option value diff --git a/clang/test/Driver/fforce-dwarf-frame.c b/clang/test/Driver/fforce-dwarf-frame.c index fb5442c56a405..c4bc2619e0ef1 100644 --- a/clang/test/Driver/fforce-dwarf-frame.c +++ b/clang/test/Driver/fforce-dwarf-frame.c @@ -1,6 +1,6 @@ -// RUN: %clang -target arm -c -### %s -fforce-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-ALWAYS %s -// RUN: %clang -target arm -c -### %s -fno-force-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s -// RUN: %clang -target arm -c -### %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s +// RUN: %clang --target=arm -c -### %s -fforce-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-ALWAYS %s +// RUN: %clang --target=arm -c -### %s -fno-force-dwarf-frame 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s +// RUN: %clang --target=arm -c -### %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ALWAYS %s // CHECK-ALWAYS: -fforce-dwarf-frame // CHECK-NO-ALWAYS-NOT: -fforce-dwarf-frame diff --git a/clang/test/Driver/fgnuc-version.c b/clang/test/Driver/fgnuc-version.c index dea82bbaae0af..c5c8ca1c159ad 100644 --- a/clang/test/Driver/fgnuc-version.c +++ b/clang/test/Driver/fgnuc-version.c @@ -2,25 +2,25 @@ // Verify -fgnuc-version parsing // -// RUN: %clang -c %s -target i686-linux -### 2>&1 | FileCheck %s -check-prefix GNUC-DEFAULT +// RUN: %clang -c %s --target=i686-linux -### 2>&1 | FileCheck %s --check-prefix=GNUC-DEFAULT // GNUC-DEFAULT: "-fgnuc-version=4.2.1" -// RUN: %clang -c %s -target i686-linux -fgnuc-version=100.99.99 -### 2>&1 | FileCheck %s -check-prefix GNUC-OVERRIDE +// RUN: %clang -c %s --target=i686-linux -fgnuc-version=100.99.99 -### 2>&1 | FileCheck %s --check-prefix=GNUC-OVERRIDE // GNUC-OVERRIDE: "-fgnuc-version=100.99.99" -// RUN: %clang -c %s -target i686-linux -fgnuc-version=0 -### 2>&1 | FileCheck %s -check-prefix GNUC-DISABLE -// RUN: %clang -c %s -target i686-linux -fgnuc-version= -### 2>&1 | FileCheck %s -check-prefix GNUC-DISABLE +// RUN: %clang -c %s --target=i686-linux -fgnuc-version=0 -### 2>&1 | FileCheck %s --check-prefix=GNUC-DISABLE +// RUN: %clang -c %s --target=i686-linux -fgnuc-version= -### 2>&1 | FileCheck %s --check-prefix=GNUC-DISABLE // GNUC-DISABLE-NOT: "-fgnuc-version= -// RUN: not %clang -c %s -target i686-linux -fgnuc-version=100.100.10 2>&1 | FileCheck %s -check-prefix GNUC-INVALID -// RUN: not %clang -c %s -target i686-linux -fgnuc-version=100.10.100 2>&1 | FileCheck %s -check-prefix GNUC-INVALID -// RUN: not %clang -c %s -target i686-linux -fgnuc-version=-1.0.0 2>&1 | FileCheck %s -check-prefix GNUC-INVALID +// RUN: not %clang -c %s --target=i686-linux -fgnuc-version=100.100.10 2>&1 | FileCheck %s --check-prefix=GNUC-INVALID +// RUN: not %clang -c %s --target=i686-linux -fgnuc-version=100.10.100 2>&1 | FileCheck %s --check-prefix=GNUC-INVALID +// RUN: not %clang -c %s --target=i686-linux -fgnuc-version=-1.0.0 2>&1 | FileCheck %s --check-prefix=GNUC-INVALID // GNUC-INVALID: error: invalid value {{.*}} in '-fgnuc-version={{.*}}' -// RUN: %clang -fgnuc-version=100.99.99 %s -dM -E -o - | FileCheck %s -check-prefix GNUC-LARGE +// RUN: %clang -fgnuc-version=100.99.99 %s -dM -E -o - | FileCheck %s --check-prefix=GNUC-LARGE // GNUC-LARGE: #define __GNUC_MINOR__ 99 // GNUC-LARGE: #define __GNUC_PATCHLEVEL__ 99 // GNUC-LARGE: #define __GNUC__ 100 -// RUN: %clang -fgnuc-version=100.99.99 -x c++ %s -dM -E -o - | FileCheck %s -check-prefix GXX-LARGE +// RUN: %clang -fgnuc-version=100.99.99 -x c++ %s -dM -E -o - | FileCheck %s --check-prefix=GXX-LARGE // GXX-LARGE: #define __GNUG__ 100 diff --git a/clang/test/Driver/flags.c b/clang/test/Driver/flags.c index da25a5cd3335c..16b760609c36d 100644 --- a/clang/test/Driver/flags.c +++ b/clang/test/Driver/flags.c @@ -25,11 +25,11 @@ // RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST8 %s // TEST8-NOT: "-no-implicit-float" -// RUN: %clang -target x86_64-linux-gnu -### -c -fclang-abi-compat=3.2 %s 2>&1 | FileCheck -check-prefix=TEST9 %s +// RUN: %clang --target=x86_64-linux-gnu -### -c -fclang-abi-compat=3.2 %s 2>&1 | FileCheck -check-prefix=TEST9 %s // TEST9: "-fclang-abi-compat=3.2" // -// RUN: %clang -target riscv32 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST10 %s +// RUN: %clang --target=riscv32 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST10 %s // TEST10: "-no-implicit-float" // -// RUN: %clang -target riscv64 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST11 %s +// RUN: %clang --target=riscv64 -### -S -mno-implicit-float %s 2>&1 | FileCheck -check-prefix=TEST11 %s // TEST11: "-no-implicit-float" diff --git a/clang/test/Driver/flang/msvc-link.f90 b/clang/test/Driver/flang/msvc-link.f90 index 536da2599431f..463749510eb5f 100644 --- a/clang/test/Driver/flang/msvc-link.f90 +++ b/clang/test/Driver/flang/msvc-link.f90 @@ -1,4 +1,4 @@ -! RUN: %clang --driver-mode=flang -target x86_64-pc-windows-msvc -### %s -Ltest 2>&1 | FileCheck %s +! RUN: %clang --driver-mode=flang --target=x86_64-pc-windows-msvc -### %s -Ltest 2>&1 | FileCheck %s ! ! Test that user provided paths come before the Flang runtimes ! CHECK: "-libpath:test" diff --git a/clang/test/Driver/fmemprof.cpp b/clang/test/Driver/fmemprof.cpp index b00d9f2c81e27..5165c4452fd57 100644 --- a/clang/test/Driver/fmemprof.cpp +++ b/clang/test/Driver/fmemprof.cpp @@ -1,7 +1,7 @@ -// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile %s -### 2>&1 | FileCheck %s -// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile=foo %s -### 2>&1 | FileCheck %s --check-prefix=DIR -// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF -// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile=foo -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF +// RUN: %clangxx --target=x86_64-linux-gnu -fmemory-profile %s -### 2>&1 | FileCheck %s +// RUN: %clangxx --target=x86_64-linux-gnu -fmemory-profile=foo %s -### 2>&1 | FileCheck %s --check-prefix=DIR +// RUN: %clangxx --target=x86_64-linux-gnu -fmemory-profile -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF +// RUN: %clangxx --target=x86_64-linux-gnu -fmemory-profile=foo -fno-memory-profile %s -### 2>&1 | FileCheck %s --check-prefix=OFF // CHECK: "-cc1" {{.*}} "-fmemory-profile" // CHECK: ld{{.*}}libclang_rt.memprof{{.*}}libclang_rt.memprof_cxx // DIR: "-cc1" {{.*}} "-fmemory-profile=foo" @@ -9,7 +9,7 @@ // OFF-NOT: "-fmemory-profile" // OFF-NOT: libclang_rt.memprof -// RUN: %clangxx -target x86_64-linux-gnu -fmemory-profile-use=foo %s -### 2>&1 | FileCheck %s --check-prefix=USE +// RUN: %clangxx --target=x86_64-linux-gnu -fmemory-profile-use=foo %s -### 2>&1 | FileCheck %s --check-prefix=USE // USE: "-cc1" {{.*}} "-fmemory-profile-use=foo" // RUN: not %clangxx --target=x86_64-linux-gnu -fmemory-profile -fmemory-profile-use=foo %s -### 2>&1 | FileCheck %s --check-prefix=CONFLICTWITHMEMPROFINSTR diff --git a/clang/test/Driver/fopenmp.c b/clang/test/Driver/fopenmp.c index 291946923b3ea..7d343eeee0f3f 100644 --- a/clang/test/Driver/fopenmp.c +++ b/clang/test/Driver/fopenmp.c @@ -1,27 +1,27 @@ -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP // RUN: %clang -target x86_64-apple-darwin -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP // RUN: %clang -target x86_64-apple-darwin -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP // RUN: %clang -target x86_64-apple-darwin -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-freebsd -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-freebsd -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-openbsd -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-openbsd -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target x86_64-openbsd -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-dragonfly -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-dragonfly -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target x86_64-dragonfly -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-windows-gnu -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP -// RUN: %clang -target x86_64-windows-gnu -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP -// RUN: %clang -target x86_64-windows-gnu -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-freebsd -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-freebsd -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=x86_64-freebsd -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-netbsd -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-netbsd -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=x86_64-netbsd -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-openbsd -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-openbsd -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=x86_64-openbsd -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-windows-gnu -fopenmp=libomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP +// RUN: %clang --target=x86_64-windows-gnu -fopenmp=libgomp -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP +// RUN: %clang --target=x86_64-windows-gnu -fopenmp=libiomp5 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP // RUN: %clang_cl --target=x86_64-windows-msvc /clang:-fopenmp=libomp /openmp -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP // RUN: %clang_cl --target=x86_64-windows-msvc /clang:-fopenmp=libgomp /openmp -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-NO-OPENMP // RUN: %clang_cl --target=x86_64-windows-msvc /clang:-fopenmp=libiomp5 /openmp -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMP @@ -36,99 +36,99 @@ // CHECK-CC1-NO-OPENMP: "-cc1" // CHECK-CC1-NO-OPENMP-NOT: "-fopenmp" // -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-RT -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-RT +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-RT -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libgomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-RT +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libiomp5 -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libiomp5 -static -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC // -// RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=x86_64-linux-gnu -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-linux-gnu -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-linux-gnu -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-darwin -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-darwin -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target x86_64-darwin -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=x86_64-darwin -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-darwin -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=x86_64-darwin -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -nostdlib -target x86_64-darwin -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-darwin -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-darwin -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=x86_64-darwin -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-darwin -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-darwin -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-freebsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-freebsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=x86_64-freebsd -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-freebsd -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=x86_64-freebsd -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -target x86_64-freebsd -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP -// RUN: %clang -target x86_64-freebsd -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT -// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 -// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// RUN: %clang --target=x86_64-freebsd -fopenmp=libomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang --target=x86_64-freebsd -fopenmp=libgomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang --target=x86_64-freebsd -fopenmp=libiomp5 -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang --target=x86_64-freebsd -fopenmp=libiomp5 -static -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC // -// RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=x86_64-freebsd -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-freebsd -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-freebsd -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-netbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=x86_64-netbsd -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-netbsd -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=x86_64-netbsd -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -target x86_64-netbsd -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT -// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 -// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// RUN: %clang --target=x86_64-netbsd -fopenmp=libomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang --target=x86_64-netbsd -fopenmp=libgomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang --target=x86_64-netbsd -fopenmp=libiomp5 -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang --target=x86_64-netbsd -fopenmp=libiomp5 -static -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC // -// RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=x86_64-netbsd -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-netbsd -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-netbsd -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-openbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-openbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target x86_64-openbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=x86_64-openbsd -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-openbsd -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=x86_64-openbsd -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -target x86_64-openbsd -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP -// RUN: %clang -target x86_64-openbsd -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT -// RUN: %clang -target x86_64-openbsd -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 -// RUN: %clang -target x86_64-openbsd -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// RUN: %clang --target=x86_64-openbsd -fopenmp=libomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang --target=x86_64-openbsd -fopenmp=libgomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang --target=x86_64-openbsd -fopenmp=libiomp5 -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang --target=x86_64-openbsd -fopenmp=libiomp5 -static -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC // -// RUN: %clang -nostdlib -target x86_64-openbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-openbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-openbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=x86_64-openbsd -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-openbsd -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-openbsd -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-dragonfly -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-dragonfly -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target x86_64-dragonfly -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -target x86_64-dragonfly -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP -// RUN: %clang -target x86_64-dragonfly -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT -// RUN: %clang -target x86_64-dragonfly -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 -// RUN: %clang -target x86_64-dragonfly -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libgomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libiomp5 -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang --target=x86_64-dragonfly -fopenmp=libiomp5 -static -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC // -// RUN: %clang -nostdlib -target x86_64-dragonfly -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-dragonfly -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-dragonfly -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=x86_64-dragonfly -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-dragonfly -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-dragonfly -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libgomp -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libiomp5 -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp=libiomp5 -static -static-openmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-OMP +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libgomp -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-GOMP --check-prefix=CHECK-LD-STATIC-GOMP-NO-RT +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libiomp5 -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5 +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp=libiomp5 -static -static-openmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC // -// RUN: %clang -nostdlib -target i386-pc-solaris2.11 -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target i386-pc-solaris2.11 -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target i386-pc-solaris2.11 -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 +// RUN: %clang -nostdlib --target=i386-pc-solaris2.11 -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=i386-pc-solaris2.11 -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=i386-pc-solaris2.11 -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-windows-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-windows-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT -// RUN: %clang -target x86_64-windows-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5MD +// RUN: %clang --target=x86_64-windows-gnu -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang --target=x86_64-windows-gnu -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang --target=x86_64-windows-gnu -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5MD // -// RUN: %clang -nostdlib -target x86_64-windows-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP -// RUN: %clang -nostdlib -target x86_64-windows-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP -// RUN: %clang -nostdlib -target x86_64-windows-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5MD +// RUN: %clang -nostdlib --target=x86_64-windows-gnu -fopenmp=libomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP +// RUN: %clang -nostdlib --target=x86_64-windows-gnu -fopenmp=libgomp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP +// RUN: %clang -nostdlib --target=x86_64-windows-gnu -fopenmp=libiomp5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5MD // // CHECK-LD-OMP: "{{.*}}ld{{(.exe)?}}" // CHECK-LD-OMP: "-lomp" @@ -172,7 +172,7 @@ // CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC: "-{{B?}}static" {{.*}} "-liomp5" // CHECK-LD-STATIC-IOMP5-NO-BDYNAMIC-NOT: "-Bdynamic" // -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libomp -fopenmp-enable-irbuilder -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMPIRBUILDER +// RUN: %clang --target=x86_64-linux-gnu -fopenmp=libomp -fopenmp-enable-irbuilder -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CC1-OPENMPIRBUILDER // // CHECK-CC1-OPENMPIRBUILDER: "-cc1" // CHECK-CC1-OPENMPIRBUILDER-SAME: "-fopenmp" @@ -184,14 +184,14 @@ // test the CC1 invocation. Instead, just ensure we do eventually link *some* // OpenMP runtime. // -// RUN: %clang -target x86_64-linux-gnu -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target x86_64-darwin -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target x86_64-freebsd -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target x86_64-netbsd -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target x86_64-openbsd -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target x86_64-dragonfly -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target i386-pc-solaris2.11 -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY -// RUN: %clang -target x86_64-windows-gnu -fopenmp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANYMD +// RUN: %clang --target=x86_64-linux-gnu -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=x86_64-darwin -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=x86_64-freebsd -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=x86_64-netbsd -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=x86_64-openbsd -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=x86_64-dragonfly -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=i386-pc-solaris2.11 -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANY +// RUN: %clang --target=x86_64-windows-gnu -fopenmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-ANYMD // // CHECK-LD-ANY: "{{.*}}ld{{(.exe)?}}" // CHECK-LD-ANY: "-l{{(omp|gomp|iomp5)}}" diff --git a/clang/test/Driver/fortran.f95 b/clang/test/Driver/fortran.f95 index db3ff2da17e88..275b1886b2fda 100644 --- a/clang/test/Driver/fortran.f95 +++ b/clang/test/Driver/fortran.f95 @@ -1,21 +1,21 @@ ! Check that the clang driver can invoke gcc to compile Fortran when in ! --driver-mode=clang. This is legacy behaviour - see also --driver-mode=flang. -! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \ +! RUN: %clang --target=x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s ! CHECK-OBJECT: gcc ! CHECK-OBJECT: "-c" ! CHECK-OBJECT: "-x" "f95" ! CHECK-OBJECT-NOT: "-cc1as" -! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ +! RUN: %clang --target=x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-ASM %s ! CHECK-ASM: gcc ! CHECK-ASM: "-S" ! CHECK-ASM: "-x" "f95" ! CHECK-ASM-NOT: "-cc1" -! RUN: %clang -Wall -target x86_64-unknown-linux-gnu -integrated-as %s -o %t -### 2>&1 | FileCheck --check-prefix=CHECK-WARN %s +! RUN: %clang -Wall --target=x86_64-unknown-linux-gnu -integrated-as %s -### 2>&1 | FileCheck --check-prefix=CHECK-WARN %s ! CHECK-WARN: gcc ! CHECK-WARN-NOT: "-Wall" ! CHECK-WARN: ld diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c index 4d0d609584c8d..ab04fd39ffa1c 100644 --- a/clang/test/Driver/fpatchable-function-entry.c +++ b/clang/test/Driver/fpatchable-function-entry.c @@ -1,23 +1,23 @@ -// RUN: %clang -target i386 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target x86_64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target aarch64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target aarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target loongarch32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s -// RUN: %clang -target riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=i386 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=x86_64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=aarch64 %s -fpatchable-function-entry=1 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=aarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=loongarch32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s // CHECK: "-fpatchable-function-entry=1" -// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s +// RUN: %clang --target=aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s // 11: "-fpatchable-function-entry=1" "-fpatchable-function-entry-offset=1" -// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s +// RUN: %clang --target=aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s // 21: "-fpatchable-function-entry=2" "-fpatchable-function-entry-offset=1" -// RUN: not %clang -target ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s +// RUN: not %clang --target=ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s // TARGET: error: unsupported option '-fpatchable-function-entry=1' for target 'ppc64' -// RUN: not %clang -target x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s +// RUN: not %clang --target=x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s // EXCESS: error: invalid argument '1,0,' to -fpatchable-function-entry= -// RUN: not %clang -target aarch64-linux -fsyntax-only %s -fxray-instrument -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=XRAY %s +// RUN: not %clang --target=aarch64-linux -fsyntax-only %s -fxray-instrument -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=XRAY %s // XRAY: error: invalid argument '-fxray-instrument' not allowed with '-fpatchable-function-entry=' diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c index e1b0a468ab825..cdedcc7ae4c89 100644 --- a/clang/test/Driver/frame-pointer-elim.c +++ b/clang/test/Driver/frame-pointer-elim.c @@ -6,39 +6,39 @@ // KEEP-NONE: "-mframe-pointer=none" // On Linux x86, omit frame pointer when optimization is enabled. -// RUN: %clang -### -target i386-linux -S -fomit-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -fomit-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target i386-linux -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // -fno-omit-frame-pointer or -pg disables frame pointer omission. -// RUN: %clang -### -target i386-linux -S %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target i386-linux -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target i386-linux -S -O1 -pg %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 -pg %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s // -momit-leaf-frame-pointer omits leaf frame pointer. // -fno-omit-frame-pointer loses out to -momit-leaf-frame-pointer. -// RUN: %clang -### -target i386 -S -momit-leaf-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386 -S -momit-leaf-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target i386-linux -S -O1 -momit-leaf-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 -momit-leaf-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // fno-omit-frame-pointer -momit-leaf-frame-pointer can be overwritten by // fomit-frame-pointer later on the command without warning -// RUN: %clang -### -target i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fomit-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fomit-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s // Explicit or default -fomit-frame-pointer wins over -mno-omit-leaf-frame-pointer. -// RUN: %clang -### -target i386 -S %s -fomit-frame-pointer -mno-omit-leaf-frame-pointer 2>&1 | \ +// RUN: %clang -### --target=i386 -S %s -fomit-frame-pointer -mno-omit-leaf-frame-pointer 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target i386-linux -S %s -O1 -mno-omit-leaf-frame-pointer 2>&1 | \ +// RUN: %clang -### --target=i386-linux -S %s -O1 -mno-omit-leaf-frame-pointer 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // -pg -fomit-frame-pointer => error. @@ -48,10 +48,10 @@ // CHECK-MIX-NO-OMIT-FP-PG-NOT: '-fomit-frame-pointer' not allowed with '-pg' // NetBSD follows the same rules as Linux. -// RUN: %clang -### -target x86_64-unknown-netbsd -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=x86_64-unknown-netbsd -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target x86_64-unknown-netbsd -S %s 2>&1 | \ +// RUN: %clang -### --target=x86_64-unknown-netbsd -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s // Darwin disables omitting the leaf frame pointer even under optimization @@ -62,10 +62,10 @@ // RUN: %clang -### -target i386-apple-darwin -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target i386-darwin -S -fomit-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-darwin -S -fomit-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \ +// RUN: %clang -### --target=i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s // RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \ @@ -85,19 +85,19 @@ // On AArch64, PS4, PS5, and VE, default to omitting the frame pointer on leaf // functions -// RUN: %clang -### -target aarch64 -S %s 2>&1 | \ +// RUN: %clang -### --target=aarch64 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target x86_64-scei-ps4 -S %s 2>&1 | \ +// RUN: %clang -### --target=x86_64-scei-ps4 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target x86_64-scei-ps4 -S -O2 %s 2>&1 | \ +// RUN: %clang -### --target=x86_64-scei-ps4 -S -O2 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target x86_64-sie-ps5 -S %s 2>&1 | \ +// RUN: %clang -### --target=x86_64-sie-ps5 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target x86_64-sie-ps5 -S -O2 %s 2>&1 | \ +// RUN: %clang -### --target=x86_64-sie-ps5 -S -O2 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s // RUN: %clang -### -target aarch64-apple-darwin -arch arm64_32 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target ve-unknown-linux-gnu -S %s 2>&1 | \ +// RUN: %clang -### --target=ve-unknown-linux-gnu -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s // RUN: %clang -### --target=aarch64-linux-android -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s @@ -106,57 +106,57 @@ // RUN: %clang -### --target=aarch64-linux-android -S -Os %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target powerpc64 -S %s 2>&1 | \ +// RUN: %clang -### --target=powerpc64 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target powerpc64 -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=powerpc64 -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // SPARC targets omit the frame pointer when optimizations are enabled. -// RUN: %clang -### -target sparc -S %s 2>&1 | \ +// RUN: %clang -### --target=sparc -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target sparc -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=sparc -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target sparcel -S %s 2>&1 | \ +// RUN: %clang -### --target=sparcel -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target sparcel -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=sparcel -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target sparc64 -S %s 2>&1 | \ +// RUN: %clang -### --target=sparc64 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target sparc64 -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=sparc64 -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // M68k targets omit the frame pointer when optimizations are enabled. -// RUN: %clang -### -target m68k -S %s 2>&1 | \ +// RUN: %clang -### --target=m68k -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target m68k -S -O1 %s 2>&1 | \ +// RUN: %clang -### --target=m68k -S -O1 %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // For AAarch32 (A32, T32) linux targets, default omit frame pointer when // optimizations are enabled. -// RUN: %clang -### -target arm-linux-gnueabihf- -marm -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -marm -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target arm-linux-gnueabihf- -mthumb -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -mthumb -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target arm-linux-gnueabihf- -marm -mbig-endian -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -marm -mbig-endian -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target arm-linux-gnueabihf- -mthumb -mbig-endian -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -mthumb -mbig-endian -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target arm-linux-gnueabihf- -marm -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -marm -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target arm-linux-gnueabihf- -mthumb -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -mthumb -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target arm-linux-gnueabihf- -marm -mbig-endian -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -marm -mbig-endian -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target arm-linux-gnueabihf- -mthumb -mbig-endian -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=arm-linux-gnueabihf- -mthumb -mbig-endian -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NONE %s // For Android, keep the framepointers always. -// RUN: %clang -### -target armv7a-linux-androideabi- -marm -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=armv7a-linux-androideabi- -marm -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target armv7a-linux-androideabi- -mthumb -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=armv7a-linux-androideabi- -mthumb -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target armv7a-linux-androideabi- -marm -mbig-endian -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=armv7a-linux-androideabi- -marm -mbig-endian -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target armv7a-linux-androideabi- -mthumb -mbig-endian -O1 -S %s 2>&1 | \ +// RUN: %clang -### --target=armv7a-linux-androideabi- -mthumb -mbig-endian -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-ALL %s // RUN: %clang -### --target=riscv64-linux-android -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s diff --git a/clang/test/Driver/freebsd-mips-as.c b/clang/test/Driver/freebsd-mips-as.c index a053c2180e52c..428644ab78a9f 100644 --- a/clang/test/Driver/freebsd-mips-as.c +++ b/clang/test/Driver/freebsd-mips-as.c @@ -1,91 +1,91 @@ // Check passing options to the assembler for MIPS targets. // -// RUN: %clang -target mips-unknown-freebsd -### \ +// RUN: %clang --target=mips-unknown-freebsd -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB-AS %s // MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB" // MIPS32-EB-AS-NOT: "-KPIC" // -// RUN: %clang -target mips-unknown-freebsd -### \ +// RUN: %clang --target=mips-unknown-freebsd -### \ // RUN: -no-integrated-as -fPIC -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB-PIC %s // MIPS32-EB-PIC: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB" // MIPS32-EB-PIC: "-KPIC" // -// RUN: %clang -target mips-unknown-freebsd -### \ +// RUN: %clang --target=mips-unknown-freebsd -### \ // RUN: -no-integrated-as -fpic -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB-PIC-SMALL %s // MIPS32-EB-PIC-SMALL: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB" // MIPS32-EB-PIC-SMALL: "-KPIC" // -// RUN: %clang -target mips-unknown-freebsd -### \ +// RUN: %clang --target=mips-unknown-freebsd -### \ // RUN: -no-integrated-as -fPIE -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB-PIE %s // MIPS32-EB-PIE: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB" // MIPS32-EB-PIE: "-KPIC" // -// RUN: %clang -target mips-unknown-freebsd -### \ +// RUN: %clang --target=mips-unknown-freebsd -### \ // RUN: -no-integrated-as -fpie -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB-PIE-SMALL %s // MIPS32-EB-PIE-SMALL: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB" // MIPS32-EB-PIE-SMALL: "-KPIC" // -// RUN: %clang -target mipsel-unknown-freebsd -### \ +// RUN: %clang --target=mipsel-unknown-freebsd -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-DEF-EL-AS %s // MIPS32-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EL" // -// RUN: %clang -target mips64-unknown-freebsd -### \ +// RUN: %clang --target=mips64-unknown-freebsd -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64-EB-AS %s // MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-EB" // -// RUN: %clang -target mips64el-unknown-freebsd -### \ +// RUN: %clang --target=mips64el-unknown-freebsd -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64-DEF-EL-AS %s // MIPS64-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-EL" // -// RUN: %clang -target mips64-unknown-freebsd -mabi=n32 -### \ +// RUN: %clang --target=mips64-unknown-freebsd -mabi=n32 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-N32 %s // MIPS-N32: as{{(.exe)?}}" "-march" "mips3" "-mabi" "n32" "-EB" // -// RUN: %clang -target mipsel-unknown-freebsd -mabi=32 -### \ +// RUN: %clang --target=mipsel-unknown-freebsd -mabi=32 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EL-AS %s // MIPS32-EL-AS: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EL" // -// RUN: %clang -target mips64el-unknown-freebsd -mabi=64 -### \ +// RUN: %clang --target=mips64el-unknown-freebsd -mabi=64 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS64-EL-AS %s // MIPS64-EL-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64" "-EL" // -// RUN: %clang -target mips-linux-freebsd -march=mips32r2 -### \ +// RUN: %clang --target=mips-linux-freebsd -march=mips32r2 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-32R2 %s // MIPS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB" // -// RUN: %clang -target mips-unknown-freebsd -mips32 -### \ +// RUN: %clang --target=mips-unknown-freebsd -mips32 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-32 %s // MIPS-ALIAS-32: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" // -// RUN: %clang -target mips-unknown-freebsd -mips32r2 -### \ +// RUN: %clang --target=mips-unknown-freebsd -mips32r2 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-32R2 %s // MIPS-ALIAS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB" // -// RUN: %clang -target mips64-unknown-freebsd -mips64 -### \ +// RUN: %clang --target=mips64-unknown-freebsd -mips64 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64 %s // MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB" // -// RUN: %clang -target mips64-unknown-freebsd -mips64r2 -### \ +// RUN: %clang --target=mips64-unknown-freebsd -mips64r2 -### \ // RUN: -no-integrated-as -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s // MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB" // -// RUN: %clang -target mips-unknown-freebsd -### \ +// RUN: %clang --target=mips-unknown-freebsd -### \ // RUN: -no-integrated-as -G0 -c %s 2>&1 \ // RUN: | FileCheck -check-prefix=MIPS32-EB-AS-G0 %s // MIPS32-EB-AS-G0: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-EB" "-G0" diff --git a/clang/test/Driver/freebsd.cpp b/clang/test/Driver/freebsd.cpp index 6ddab91999055..dc8c98d3c3cb7 100644 --- a/clang/test/Driver/freebsd.cpp +++ b/clang/test/Driver/freebsd.cpp @@ -1,15 +1,15 @@ -// RUN: %clangxx %s -### -o %t.o -target amd64-unknown-freebsd -stdlib=platform 2>&1 \ +// RUN: %clangxx %s -### -o %t.o --target=amd64-unknown-freebsd -stdlib=platform 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-DEFAULT %s -// RUN: %clangxx %s -### -o %t.o -target amd64-unknown-freebsd10.0 -stdlib=platform 2>&1 \ +// RUN: %clangxx %s -### -o %t.o --target=amd64-unknown-freebsd10.0 -stdlib=platform 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-TEN %s // CHECK-DEFAULT: "-lc++" "-lm" // CHECK-TEN: "-lc++" "-lm" -// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd -stdlib=platform 2>&1 \ +// RUN: %clangxx %s -### -pg -o %t.o --target=amd64-unknown-freebsd -stdlib=platform 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PG-DEFAULT %s -// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd14.0 -stdlib=platform 2>&1 \ +// RUN: %clangxx %s -### -pg -o %t.o --target=amd64-unknown-freebsd14.0 -stdlib=platform 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PG-FOURTEEN %s -// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd10.0 -stdlib=platform 2>&1 \ +// RUN: %clangxx %s -### -pg -o %t.o --target=amd64-unknown-freebsd10.0 -stdlib=platform 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PG-TEN %s // CHECK-PG-DEFAULT: "-lc++" "-lm" // CHECK-PG-FOURTEEN: "-lc++" "-lm" diff --git a/clang/test/Driver/fsanitize-coverage.c b/clang/test/Driver/fsanitize-coverage.c index d34ad5f6698fa..c2de897f80eeb 100644 --- a/clang/test/Driver/fsanitize-coverage.c +++ b/clang/test/Driver/fsanitize-coverage.c @@ -1,45 +1,45 @@ -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-0 -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge -fsanitize-coverage=0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-0 -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-0 +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-0 +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge -fsanitize-coverage=0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-0 +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-0 // CHECK-SANITIZE-COVERAGE-0-NOT: fsanitize-coverage-type // CHECK-SANITIZE-COVERAGE-0: -fsanitize=address -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=leak -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=bounds -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=bool -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=dataflow -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize=kcfi -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target %itanium_abi_triple -fsanitize=float-divide-by-zero -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=kernel-address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=kernel-hwaddress -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=kernel-memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=leak -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=bounds -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=bool -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=dataflow -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=thread -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=kcfi -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=%itanium_abi_triple -fsanitize=float-divide-by-zero -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // CHECK-SANITIZE-COVERAGE-FUNC: fsanitize-coverage-type=1 -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-BB +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-BB // CHECK-SANITIZE-COVERAGE-BB: fsanitize-coverage-type=2 -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-EDGE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-EDGE // CHECK-SANITIZE-COVERAGE-EDGE: fsanitize-coverage-type=3 -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC_INDIR +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC_INDIR // CHECK-SANITIZE-COVERAGE-FUNC_INDIR: fsanitize-coverage-type=3 // CHECK-SANITIZE-COVERAGE-FUNC_INDIR: fsanitize-coverage-indirect-calls -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-1 +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-1 // CHECK-SANITIZE-COVERAGE-1: warning: argument '-fsanitize-coverage=1' is deprecated, use '-fsanitize-coverage=trace-pc-guard' instead -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_FUNC_BB_EDGE_DEPRECATED -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_FUNC_BB_EDGE_DEPRECATED -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_FUNC_BB_EDGE_DEPRECATED +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_FUNC_BB_EDGE_DEPRECATED +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_FUNC_BB_EDGE_DEPRECATED +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_FUNC_BB_EDGE_DEPRECATED // CHECK_FUNC_BB_EDGE_DEPRECATED: warning: argument '-fsanitize-coverage=[func|bb|edge]' is deprecated, use '-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc],[control-flow]' instead -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge,indirect-calls,trace-pc,trace-cmp,trace-loads,trace-stores,trace-div,trace-gep %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FEATURES +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=edge,indirect-calls,trace-pc,trace-cmp,trace-loads,trace-stores,trace-div,trace-gep %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FEATURES // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-type=3 // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-indirect-calls // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-trace-cmp @@ -49,7 +49,7 @@ // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-trace-loads // CHECK-SANITIZE-COVERAGE-FEATURES: -fsanitize-coverage-trace-stores -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,edge,indirect-calls,trace-cmp -fno-sanitize-coverage=edge,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MASK +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,edge,indirect-calls,trace-cmp -fno-sanitize-coverage=edge,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MASK // CHECK-MASK: -fsanitize-coverage-type=1 // CHECK-MASK: -fsanitize-coverage-trace-cmp // CHECK-MASK-NOT: -fsanitize-coverage- @@ -60,30 +60,30 @@ // RUN: not %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func -fsanitize-coverage=edge %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INCOMPATIBLE // CHECK-INCOMPATIBLE: error: invalid argument '-fsanitize-coverage=func' not allowed with '-fsanitize-coverage=edge' -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-8BIT +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-8BIT // CHECK-8BIT: warning: argument '-fsanitize-coverage=8bit-counters' is deprecated, use '-fsanitize-coverage=trace-pc-guard' instead -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE-BB +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=trace-bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE-BB // CHECK-TRACE-BB: warning: argument '-fsanitize-coverage=trace-bb' is deprecated, use '-fsanitize-coverage=trace-pc-guard' instead -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_EDGE -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=edge,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_EDGE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_EDGE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=edge,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_EDGE // CHECK-TRACE_PC_EDGE: -fsanitize-coverage-type=3 // CHECK-TRACE_PC_EDGE: -fsanitize-coverage-trace-pc -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_FUNC // CHECK-TRACE_PC_FUNC: -fsanitize-coverage-type=1 // CHECK-TRACE_PC_FUNC: -fsanitize-coverage-trace-pc -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_GUARD_EDGE -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=edge,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_GUARD_EDGE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_GUARD_EDGE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=edge,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_GUARD_EDGE // CHECK-TRACE_PC_GUARD_EDGE: -fsanitize-coverage-type=3 // CHECK-TRACE_PC_GUARD_EDGE: -fsanitize-coverage-trace-pc-guard -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=func,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_GUARD_FUNC +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=func,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACE_PC_GUARD_FUNC // CHECK-TRACE_PC_GUARD_FUNC: -fsanitize-coverage-type=1 // CHECK-TRACE_PC_GUARD_FUNC: -fsanitize-coverage-trace-pc-guard -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=stack-depth %s \ +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=stack-depth %s \ // RUN: -### 2>&1 | FileCheck %s --check-prefix=CHECK-STACK-DEPTH -// RUN: %clang -target x86_64-linux-gnu \ +// RUN: %clang --target=x86_64-linux-gnu \ // RUN: -fsanitize-coverage=trace-pc-guard,stack-depth %s -### 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK-STACK-DEPTH-PC-GUARD // CHECK-STACK-DEPTH: -fsanitize-coverage-type=1 @@ -92,35 +92,35 @@ // CHECK-STACK-DEPTH-PC-GUARD: -fsanitize-coverage-trace-pc-guard // CHECK-STACK-DEPTH-PC-GUARD: -fsanitize-coverage-stack-depth -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=trace-cmp,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TYPE-NECESSARY +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=trace-cmp,indirect-calls %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TYPE-NECESSARY // CHECK-NO-TYPE-NECESSARY-NOT: error: // CHECK-NO-TYPE-NECESSARY: -fsanitize-coverage-indirect-calls // CHECK-NO-TYPE-NECESSARY: -fsanitize-coverage-trace-cmp -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func -fsanitize-coverage=trace-cmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-EXTEND-LEGACY +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func -fsanitize-coverage=trace-cmp %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-EXTEND-LEGACY // CHECK-EXTEND-LEGACY: -fsanitize-coverage-type=1 // CHECK-EXTEND-LEGACY: -fsanitize-coverage-trace-cmp -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=no-prune,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=no-prune,func,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=no-prune,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=no-prune,func,trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_NOPRUNE // CHECK_NOPRUNE: -fsanitize-coverage-no-prune -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=bb,inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=bb,inline-8bit-counters %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE8BIT // CHECK_INLINE8BIT-NOT: warning: // CHECK_INLINE8BIT: -fsanitize-coverage-inline-8bit-counters -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=inline-8bit-counters,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINE8BIT // CHECK_PC_TABLE_FOR_INLINE8BIT: -fsanitize-coverage-pc-table -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=bb,inline-bool-flag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=bb,inline-bool-flag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_INLINE_BOOL_FLAG // CHECK_INLINE_BOOL_FLAG-NOT: warning: // CHECK_INLINE_BOOL_FLAG: -fsanitize-coverage-inline-bool-flag -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL -// RUN: %clang -target x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=inline-bool-flag,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-coverage=trace-pc-guard,pc-table %s -### 2>&1 | FileCheck %s --check-prefix=CHECK_PC_TABLE_FOR_INLINEBOOL // CHECK_PC_TABLE_FOR_INLINEBOOL: -fsanitize-coverage-pc-table // RUN: %clang_cl --target=i386-pc-win32 -fsanitize=address -fsanitize-coverage=func,trace-pc-guard -c -### -- %s 2>&1 | FileCheck %s -check-prefix=CLANG-CL-COVERAGE @@ -131,11 +131,11 @@ // CLANG-CL-COVERAGE: -fsanitize-coverage-type=1 // CLANG-CL-COVERAGE: -fsanitize=address -// RUN: %clang -target x86_64-linux-gnu -fsanitize=safe-stack -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VS-SAFESTACK +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=safe-stack -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VS-SAFESTACK // CHECK-VS-SAFESTACK: -fsanitize-coverage-trace-pc-guard // CHECK-VS-SAFESTACK: -fsanitize=safe-stack -// RUN: %clang -target x86_64-linux-gnu -fsanitize=safe-stack -fsanitize-coverage=trace-pc-guard -fno-sanitize=safe-stack %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SAFESTACK +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=safe-stack -fsanitize-coverage=trace-pc-guard -fno-sanitize=safe-stack %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SAFESTACK // CHECK-NO-SAFESTACK-NOT: error: // CHECK-NO-SAFESTACK-NOT: warning: // CHECK-NO-SAFESTACK-NOT: argument unused @@ -143,11 +143,11 @@ // CHECK-NO-SAFESTACK-NOT: -fsanitize=safe-stack // CHECK-NO-SAFESTACK: -fsanitize-coverage-trace-pc-guard -// RUN: %clang -target x86_64-linux-gnu -fsanitize=shadow-call-stack -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VS-SHADOWCALLSTACK +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=shadow-call-stack -fsanitize-coverage=trace-pc-guard %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VS-SHADOWCALLSTACK // CHECK-VS-SHADOWCALLSTACK: -fsanitize-coverage-trace-pc-guard // CHECK-VS-SHADOWCALLSTACK: -fsanitize=shadow-call-stack -// RUN: %clang -target x86_64-linux-gnu -fsanitize=shadow-call-stack -fsanitize-coverage=trace-pc-guard -fno-sanitize=shadow-call-stack %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SAFESTACK +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=shadow-call-stack -fsanitize-coverage=trace-pc-guard -fno-sanitize=shadow-call-stack %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SAFESTACK // CHECK-NO-SHADOWCALLSTACK-NOT: error: // CHECK-NO-SHADOWCALLSTACK-NOT: warning: // CHECK-NO-SHADOWCALLSTACK-NOT: argument unused diff --git a/clang/test/Driver/fsanitize-ignorelist.c b/clang/test/Driver/fsanitize-ignorelist.c index c4669e50bb091..7dd666a453198 100644 --- a/clang/test/Driver/fsanitize-ignorelist.c +++ b/clang/test/Driver/fsanitize-ignorelist.c @@ -11,37 +11,37 @@ // RUN: echo "fun:bar" > %t.second // RUN: echo "badline" > %t.bad -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORELIST -// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress -fsanitize-ignorelist=%t.good -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORELIST +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORELIST +// RUN: %clang --target=aarch64-linux-gnu -fsanitize=hwaddress -fsanitize-ignorelist=%t.good -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORELIST // CHECK-IGNORELIST: -fsanitize-ignorelist={{.*}}.good" "-fsanitize-ignorelist={{.*}}.second // Check that the default ignorelist is not added as an extra dependency. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-IGNORELIST-ASAN --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-IGNORELIST-ASAN --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= // CHECK-DEFAULT-IGNORELIST-ASAN: -fsanitize-system-ignorelist={{.*[^w]}}asan_ignorelist.txt -// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-IGNORELIST-HWASAN --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=hwaddress -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-IGNORELIST-HWASAN --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= // CHECK-DEFAULT-IGNORELIST-HWASAN: -fsanitize-system-ignorelist={{.*}}hwasan_ignorelist.txt -// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= -// RUN: %clang -target x86_64-linux-gnu -fsanitize=nullability -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= -// RUN: %clang -target x86_64-linux-gnu -fsanitize=alignment -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= -// RUN: %clang -target %itanium_abi_triple -fsanitize=float-divide-by-zero -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=integer -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=nullability -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=alignment -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=%itanium_abi_triple -fsanitize=float-divide-by-zero -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= // CHECK-DEFAULT-UBSAN-IGNORELIST: -fsanitize-system-ignorelist={{.*}}ubsan_ignorelist.txt // Check that combining ubsan and another sanitizer results in both ignorelists being used. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined,address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --check-prefix=CHECK-DEFAULT-IGNORELIST-ASAN --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined,address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-IGNORELIST --check-prefix=CHECK-DEFAULT-IGNORELIST-ASAN --implicit-check-not=fdepfile-entry --implicit-check-not=-fsanitize-ignorelist= // Ignore -fsanitize-ignorelist flag if there is no -fsanitize flag. -// RUN: %clang -target x86_64-linux-gnu -fsanitize-ignorelist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE --check-prefix=DELIMITERS +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-ignorelist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE --check-prefix=DELIMITERS // CHECK-NO-SANITIZE-NOT: -fsanitize-ignorelist // Ignore -fsanitize-ignorelist flag if there is no -fsanitize flag. // Now, check for the absence of -fdepfile-entry flags. -// RUN: %clang -target x86_64-linux-gnu -fsanitize-ignorelist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE2 --check-prefix=DELIMITERS +// RUN: %clang --target=x86_64-linux-gnu -fsanitize-ignorelist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE2 --check-prefix=DELIMITERS // CHECK-NO-SANITIZE2-NOT: -fdepfile-entry // Flag -fno-sanitize-ignorelist wins if it is specified later. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fno-sanitize-ignorelist %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IGNORELIST --check-prefix=DELIMITERS +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fno-sanitize-ignorelist %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IGNORELIST --check-prefix=DELIMITERS // CHECK-NO-IGNORELIST-NOT: -fsanitize-ignorelist // Driver barks on unexisting ignorelist files. @@ -53,13 +53,13 @@ // CHECK-BAD-IGNORELIST: error: malformed sanitizer ignorelist: 'error parsing file '{{.*}}.bad': malformed line 1: 'badline'' // -fno-sanitize-ignorelist disables all ignorelists specified earlier. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fno-sanitize-ignorelist -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-FIRST-DISABLED --implicit-check-not=-fsanitize-ignorelist= +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fno-sanitize-ignorelist -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-FIRST-DISABLED --implicit-check-not=-fsanitize-ignorelist= // CHECK-ONLY_FIRST-DISABLED-NOT: good // CHECK-ONLY-FIRST-DISABLED: -fsanitize-ignorelist={{.*}}.second // CHECK-ONLY_FIRST-DISABLED-NOT: good // -fno-sanitize-ignorelist disables the system ignorelists. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize-ignorelist %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DISABLED-SYSTEM --check-prefix=DELIMITERS +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fno-sanitize-ignorelist %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DISABLED-SYSTEM --check-prefix=DELIMITERS // CHECK-DISABLED-SYSTEM-NOT: -fsanitize-system-ignorelist // If cfi_ignorelist.txt cannot be found in the resource dir, driver should fail. @@ -67,7 +67,7 @@ // CHECK-MISSING-CFI-IGNORELIST: error: missing sanitizer ignorelist: '{{.*}}cfi_ignorelist.txt' // -fno-sanitize-ignorelist disables checking for cfi_ignorelist.txt in the resource dir. -// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -fvisibility=default -fno-sanitize-ignorelist -resource-dir=/dev/null %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MISSING-CFI-NO-IGNORELIST +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=cfi -flto -fvisibility=default -fno-sanitize-ignorelist -resource-dir=/dev/null %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MISSING-CFI-NO-IGNORELIST // CHECK-MISSING-CFI-NO-IGNORELIST-NOT: error: no such file or directory: '{{.*}}cfi_ignorelist.txt' // DELIMITERS: {{^ *"}} diff --git a/clang/test/Driver/fsanitize-memory-param-retval.c b/clang/test/Driver/fsanitize-memory-param-retval.c index 79ade32178b69..99d8cb7f55e5d 100644 --- a/clang/test/Driver/fsanitize-memory-param-retval.c +++ b/clang/test/Driver/fsanitize-memory-param-retval.c @@ -1,14 +1,14 @@ -// RUN: %clang -target i386-gnu-linux %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s -// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s -// RUN: %clang -target aarch64-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s -// RUN: %clang -target riscv32-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s -// RUN: %clang -target riscv64-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s -// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=kernel-memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=i386-gnu-linux %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=x86_64-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=aarch64-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=riscv32-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=riscv64-linux-gnu %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang --target=x86_64-linux-gnu %s -fsanitize=kernel-memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck %s // CHECK: "-fno-sanitize-memory-param-retval" -// RUN: %clang -target aarch64-linux-gnu -fsyntax-only %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck --check-prefix=11 %s +// RUN: %clang --target=aarch64-linux-gnu -fsyntax-only %s -fsanitize=memory -fno-sanitize-memory-param-retval -c -### 2>&1 | FileCheck --check-prefix=11 %s // 11: "-fno-sanitize-memory-param-retval" -// RUN: not %clang -target x86_64-linux-gnu -fsyntax-only %s -fsanitize=memory -fno-sanitize-memory-param-retval=1 2>&1 | FileCheck --check-prefix=EXCESS %s +// RUN: not %clang --target=x86_64-linux-gnu -fsyntax-only %s -fsanitize=memory -fno-sanitize-memory-param-retval=1 2>&1 | FileCheck --check-prefix=EXCESS %s // EXCESS: error: unknown argument: '-fno-sanitize-memory-param-retval= diff --git a/clang/test/Driver/fsanitize-metadata-ignorelist.c b/clang/test/Driver/fsanitize-metadata-ignorelist.c index 65a45ccb1404f..ad5f4be167683 100644 --- a/clang/test/Driver/fsanitize-metadata-ignorelist.c +++ b/clang/test/Driver/fsanitize-metadata-ignorelist.c @@ -3,12 +3,12 @@ // RUN: echo "fun:foo" > %t.1 // RUN: echo "fun:bar" > %t.2 -// RUN: %clang -target x86_64-linux-gnu -fexperimental-sanitize-metadata=all -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s -// RUN: %clang -target aarch64-linux-gnu -fexperimental-sanitize-metadata=atomics -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s +// RUN: %clang --target=x86_64-linux-gnu -fexperimental-sanitize-metadata=all -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s +// RUN: %clang --target=aarch64-linux-gnu -fexperimental-sanitize-metadata=atomics -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s // CHECK: "-fexperimental-sanitize-metadata-ignorelist={{.*}}.1" "-fexperimental-sanitize-metadata-ignorelist={{.*}}.2" // Verify -fsanitize-metadata-ignorelist flag not passed if there is no -fsanitize-metadata flag. -// RUN: %clang -target x86_64-linux-gnu -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s --check-prefix=NOSANMD -// RUN: %clang -target aarch64-linux-gnu -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s --check-prefix=NOSANMD +// RUN: %clang --target=x86_64-linux-gnu -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s --check-prefix=NOSANMD +// RUN: %clang --target=aarch64-linux-gnu -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s --check-prefix=NOSANMD // NOSANMD: warning: argument unused during compilation: '-fexperimental-sanitize-metadata-ignorelist // NOSANMD-NOT: "-fexperimental-sanitize-metadata-ignorelist diff --git a/clang/test/Driver/fsanitize-object-size.c b/clang/test/Driver/fsanitize-object-size.c index 50c67838df39a..78c7202886416 100644 --- a/clang/test/Driver/fsanitize-object-size.c +++ b/clang/test/Driver/fsanitize-object-size.c @@ -1,27 +1,27 @@ // Check that the object size check is disabled at -O0. // -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size %s -O0 -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=null,object-size %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE -// RUN: %clang -target x86_64-linux-gnu -Werror -fsanitize=null,object-size %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE-NO-WARNING +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size %s -O0 -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=null,object-size %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -Werror -fsanitize=null,object-size %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OSIZE-NO-WARNING // Check that the object size check is enabled at other optimization levels. // -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -O2 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -O3 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -O4 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -Ofast %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -Os %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -Oz %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=object-size -Og %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -O2 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -O3 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -O4 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -Ofast %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -Os %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -Oz %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=object-size -Og %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE // Use of trap mode shouldn't affect the object size check. // -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE -// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-trap=undefined -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined-trap -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error -O1 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HAS-OSIZE // CHECK-HAS-OSIZE-NOT: warning: the object size sanitizer // CHECK-HAS-OSIZE: -fsanitize={{[^ ]*}}object-size diff --git a/clang/test/Driver/fsemantic-interposition.c b/clang/test/Driver/fsemantic-interposition.c index 0ee0dbb3be347..aaa44878483c5 100644 --- a/clang/test/Driver/fsemantic-interposition.c +++ b/clang/test/Driver/fsemantic-interposition.c @@ -1,20 +1,20 @@ -// RUN: %clang --sysroot=%S/Inputs -target x86_64 %s -Werror -fpic -fsemantic-interposition -c -### 2>&1 | FileCheck %s -// RUN: %clang --sysroot=%S/Inputs -target x86_64 %s -Werror -fPIC -fsemantic-interposition -c -### 2>&1 | FileCheck %s +// RUN: %clang --sysroot=%S/Inputs --target=x86_64 %s -Werror -fpic -fsemantic-interposition -c -### 2>&1 | FileCheck %s +// RUN: %clang --sysroot=%S/Inputs --target=x86_64 %s -Werror -fPIC -fsemantic-interposition -c -### 2>&1 | FileCheck %s // CHECK: "-fsemantic-interposition" /// No-op for -fno-pic/-fpie. -// RUN: %clang --sysroot=%S/Inputs -target x86_64 %s -Werror -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s -// RUN: %clang --sysroot=%S/Inputs -target x86_64 %s -Werror -fPIE -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s +// RUN: %clang --sysroot=%S/Inputs --target=x86_64 %s -Werror -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s +// RUN: %clang --sysroot=%S/Inputs --target=x86_64 %s -Werror -fPIE -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s // NOOP-NOT: "-fsemantic-interposition" // NOOP-NOT: "-fno-semantic-interposition" /// If -fno-semantic-interposition is specified and the target supports local /// aliases, neither CC1 option is set. -// RUN: %clang --sysroot=%S/Inputs -target aarch64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s -// RUN: %clang --sysroot=%S/Inputs -target riscv32 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s -// RUN: %clang --sysroot=%S/Inputs -target riscv64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s -// RUN: %clang --sysroot=%S/Inputs -target i386 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s -// RUN: %clang --sysroot=%S/Inputs -target x86_64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s +// RUN: %clang --sysroot=%S/Inputs --target=aarch64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s +// RUN: %clang --sysroot=%S/Inputs --target=riscv32 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s +// RUN: %clang --sysroot=%S/Inputs --target=riscv64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s +// RUN: %clang --sysroot=%S/Inputs --target=i386 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s +// RUN: %clang --sysroot=%S/Inputs --target=x86_64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s // NO-NOT: "-fsemantic-interposition" // NO-NOT: "-fhalf-no-semantic-interposition" @@ -23,8 +23,8 @@ /// local aliases, use the traditional half-baked behavor: interprocedural /// optimizations are allowed but local aliases are not used. If references are /// not optimized out, semantic interposition at runtime is possible. -// RUN: %clang --sysroot=%S/Inputs -target ppc64le %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=HALF %s +// RUN: %clang --sysroot=%S/Inputs --target=ppc64le %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=HALF %s -// RUN: %clang --sysroot=%S/Inputs -target x86_64 %s -Werror -fPIC -c -### 2>&1 | FileCheck --check-prefix=HALF %s +// RUN: %clang --sysroot=%S/Inputs --target=x86_64 %s -Werror -fPIC -c -### 2>&1 | FileCheck --check-prefix=HALF %s // // HALF: "-fhalf-no-semantic-interposition" diff --git a/clang/test/Driver/fsjlj-exceptions.c b/clang/test/Driver/fsjlj-exceptions.c index fd16a51b1f692..122513f6b611a 100644 --- a/clang/test/Driver/fsjlj-exceptions.c +++ b/clang/test/Driver/fsjlj-exceptions.c @@ -1,6 +1,6 @@ // RUN: %clang -target armv7-apple-ios -fexceptions -c %s -o /dev/null -### 2>&1 | FileCheck -check-prefix CHECK-IOS %s -// RUN: %clang -target i686-windows-gnu -fexceptions -c %s -o /dev/null -### 2>&1 | FileCheck -check-prefix CHECK-MINGW-DEFAULT %s -// RUN: %clang -target i686-windows-gnu -fexceptions -fsjlj-exceptions -c %s -o /dev/null -### 2>&1 | FileCheck -check-prefix CHECK-MINGW-SJLJ %s +// RUN: %clang --target=i686-windows-gnu -fexceptions -c %s -o /dev/null -### 2>&1 | FileCheck --check-prefix=CHECK-MINGW-DEFAULT %s +// RUN: %clang --target=i686-windows-gnu -fexceptions -fsjlj-exceptions -c %s -o /dev/null -### 2>&1 | FileCheck --check-prefix=CHECK-MINGW-SJLJ %s // CHECK-IOS: -exception-model=sjlj // CHECK-MINGW-DEFAULT-NOT: -exception-model=sjlj diff --git a/clang/test/Driver/fuse-ld-windows.c b/clang/test/Driver/fuse-ld-windows.c index 089f2961b75dc..8a5af61c6e092 100644 --- a/clang/test/Driver/fuse-ld-windows.c +++ b/clang/test/Driver/fuse-ld-windows.c @@ -1,23 +1,23 @@ // REQUIRES: system-windows // We used to require adding ".exe" suffix when cross-compiling on Windows. -// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: -B %S/Inputs/fuse_ld_windows -fuse-ld=foo 2>&1 \ // RUN: | FileCheck %s // Check that the old variant still works. -// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: -B %S/Inputs/fuse_ld_windows -fuse-ld=foo.exe 2>&1 \ // RUN: | FileCheck %s // With the full path, the extension can be omitted, too, // because Windows allows that. -// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/ld.foo 2>&1 \ // RUN: | FileCheck %s // Check that the full path with the extension works too. -// RUN: %clang %s -### -o %t.o -target i386-unknown-linux \ +// RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: -fuse-ld=%S/Inputs/fuse_ld_windows/ld.foo.exe 2>&1 \ // RUN: | FileCheck %s diff --git a/clang/test/Driver/fuse-ld.c b/clang/test/Driver/fuse-ld.c index ef2f8c92a3706..f807434dad107 100644 --- a/clang/test/Driver/fuse-ld.c +++ b/clang/test/Driver/fuse-ld.c @@ -15,88 +15,88 @@ // CHECK-NO-WARN-NOT: warning: // RUN: %clang %s -### \ -// RUN: -target x86_64-unknown-freebsd 2>&1 \ +// RUN: --target=x86_64-unknown-freebsd 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-FREEBSD-LD // CHECK-FREEBSD-LD: ld // RUN: %clang %s -### -fuse-ld=bfd \ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree \ -// RUN: -target x86_64-unknown-freebsd \ +// RUN: --target=x86_64-unknown-freebsd \ // RUN: -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-FREEBSD-BFD // CHECK-FREEBSD-BFD: Inputs/basic_freebsd_tree/usr/bin{{/|\\+}}ld.bfd // RUN: %clang %s -### -fuse-ld=gold \ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree \ -// RUN: -target x86_64-unknown-freebsd \ +// RUN: --target=x86_64-unknown-freebsd \ // RUN: -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-FREEBSD-GOLD // CHECK-FREEBSD-GOLD: Inputs/basic_freebsd_tree/usr/bin{{/|\\+}}ld.gold // RUN: not %clang %s -### -fuse-ld=plib \ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree \ -// RUN: -target x86_64-unknown-freebsd \ +// RUN: --target=x86_64-unknown-freebsd \ // RUN: -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-FREEBSD-PLIB // CHECK-FREEBSD-PLIB: error: invalid linker name // RUN: %clang %s -### -fuse-ld=ld \ -// RUN: -target arm-linux-androideabi \ +// RUN: --target=arm-linux-androideabi \ // RUN: -B%S/Inputs/basic_android_tree/bin/arm-linux-androideabi- 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD // CHECK-ANDROID-ARM-LD: ld.lld // RUN: %clang %s -### -fuse-ld=bfd \ -// RUN: -target arm-linux-androideabi \ +// RUN: --target=arm-linux-androideabi \ // RUN: -B%S/Inputs/basic_android_tree/bin/arm-linux-androideabi- 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD // CHECK-ANDROID-ARM-BFD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld.bfd // RUN: %clang %s -### -fuse-ld=gold \ -// RUN: -target arm-linux-androideabi \ +// RUN: --target=arm-linux-androideabi \ // RUN: -B%S/Inputs/basic_android_tree/bin/arm-linux-androideabi- 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD // CHECK-ANDROID-ARM-GOLD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld.gold // RUN: %clang %s -### -fuse-ld=ld \ -// RUN: -target arm-linux-androideabi \ +// RUN: --target=arm-linux-androideabi \ // RUN: --gcc-toolchain=%S/Inputs/basic_android_tree 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD-TC // CHECK-ANDROID-ARM-LD-TC: ld.lld // RUN: %clang %s -### -fuse-ld=bfd \ -// RUN: -target arm-linux-androideabi \ +// RUN: --target=arm-linux-androideabi \ // RUN: --gcc-toolchain=%S/Inputs/basic_android_tree 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD-TC // CHECK-ANDROID-ARM-BFD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.bfd // RUN: %clang %s -### -fuse-ld=gold \ -// RUN: -target arm-linux-androideabi \ +// RUN: --target=arm-linux-androideabi \ // RUN: --gcc-toolchain=%S/Inputs/basic_android_tree 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC // CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.gold // RUN: %clang %s -### -fuse-ld=link \ -// RUN: -target i686-unknown-windows-msvc 2>&1 \ +// RUN: --target=i686-unknown-windows-msvc 2>&1 \ // RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LINK // CHECK-WINDOWS-MSVC-LINK: "{{.*}}link.exe" // CHECK-WINDOWS-MSVC-LINK-SAME: "-out:{{.*}}" // RUN: %clang %s -### -fuse-ld=lld \ -// RUN: -target i686-unknown-windows-msvc 2>&1 \ +// RUN: --target=i686-unknown-windows-msvc 2>&1 \ // RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LLD // CHECK-WINDOWS-MSVC-LLD: "{{.*}}lld-link{{\.exe"|"}} // CHECK-WINDOWS-MSVC-LLD-SAME: "-out:{{.*}}" // RUN: %clang %s -### -fuse-ld=lld-link \ -// RUN: -target i686-unknown-windows-msvc 2>&1 \ +// RUN: --target=i686-unknown-windows-msvc 2>&1 \ // RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LLD-LINK // CHECK-WINDOWS-MSVC-LLD-LINK: "{{.*}}lld-link{{\.exe"|"}} // CHECK-WINDOWS-MSVC-LLD-LINK-SAME: "-out:{{.*}}" // RUN: %clang %s -### -fuse-ld=bfd \ -// RUN: -target i686-unknown-windows-msvc \ +// RUN: --target=i686-unknown-windows-msvc \ // RUN: -B %S/Inputs/Windows/usr/bin 2>&1 \ // RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-BFD // CHECK-WINDOWS-MSVC-BFD: "{{.*}}ld.bfd" diff --git a/clang/test/Driver/fuzzer.c b/clang/test/Driver/fuzzer.c index 14caf7690057d..409fbfac8ce1d 100644 --- a/clang/test/Driver/fuzzer.c +++ b/clang/test/Driver/fuzzer.c @@ -8,7 +8,7 @@ // CHECK-COVERAGE-SAME: -fsanitize-coverage-pc-table // CHECK-FUZZER-LIB: libclang_rt.fuzzer -// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=platform %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-LINUX %s +// RUN: %clang -fsanitize=fuzzer --target=i386-unknown-linux -stdlib=platform %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-LINUX %s // // CHECK-LIBCXX-LINUX: -lstdc++ @@ -29,18 +29,18 @@ // Check that we respect whether thes tandard library should be linked // statically. // -// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=libstdc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBSTDCXX-DYNAMIC %s +// RUN: %clang -fsanitize=fuzzer --target=i386-unknown-linux -stdlib=libstdc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBSTDCXX-DYNAMIC %s // CHECK-LIBSTDCXX-DYNAMIC-NOT: -Bstatic // CHECK-LIBSTDCXX-DYNAMIC: -lstdc++ // -// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=libstdc++ -static-libstdc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBSTDCXX-STATIC %s +// RUN: %clang -fsanitize=fuzzer --target=i386-unknown-linux -stdlib=libstdc++ -static-libstdc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBSTDCXX-STATIC %s // CHECK-LIBSTDCXX-STATIC: "-Bstatic" "-lstdc++" // -// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=libc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-DYNAMIC %s +// RUN: %clang -fsanitize=fuzzer --target=i386-unknown-linux -stdlib=libc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-DYNAMIC %s // CHECK-LIBCXX-DYNAMIC-NOT: -Bstatic // CHECK-LIBCXX-DYNAMIC: -lc++ // -// RUN: %clang -fsanitize=fuzzer -target i386-unknown-linux -stdlib=libc++ -static-libstdc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-STATIC %s +// RUN: %clang -fsanitize=fuzzer --target=i386-unknown-linux -stdlib=libc++ -static-libstdc++ %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LIBCXX-STATIC %s // CHECK-LIBCXX-STATIC: "-Bstatic" "-lc++" int LLVMFuzzerTestOneInput(const char *Data, long Size) { diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c index 8a230284bcdfe..9b0f1ce13aa2b 100644 --- a/clang/test/Driver/fveclib.c +++ b/clang/test/Driver/fveclib.c @@ -1,11 +1,11 @@ -// RUN: %clang -### -c -fveclib=none %s 2>&1 | FileCheck -check-prefix CHECK-NOLIB %s -// RUN: %clang -### -c -fveclib=Accelerate %s 2>&1 | FileCheck -check-prefix CHECK-ACCELERATE %s -// RUN: %clang -### -c -fveclib=libmvec %s 2>&1 | FileCheck -check-prefix CHECK-libmvec %s -// RUN: %clang -### -c -fveclib=MASSV %s 2>&1 | FileCheck -check-prefix CHECK-MASSV %s -// RUN: %clang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck -check-prefix CHECK-DARWIN_LIBSYSTEM_M %s -// RUN: %clang -### -c --target=aarch64-none-none -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-SLEEF %s -// RUN: %clang -### -c --target=aarch64-none-none -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ARMPL %s -// RUN: not %clang -c -fveclib=something %s 2>&1 | FileCheck -check-prefix CHECK-INVALID %s +// RUN: %clang -### -c -fveclib=none %s 2>&1 | FileCheck --check-prefix=CHECK-NOLIB %s +// RUN: %clang -### -c -fveclib=Accelerate %s 2>&1 | FileCheck --check-prefix=CHECK-ACCELERATE %s +// RUN: %clang -### -c -fveclib=libmvec %s 2>&1 | FileCheck --check-prefix=CHECK-libmvec %s +// RUN: %clang -### -c -fveclib=MASSV %s 2>&1 | FileCheck --check-prefix=CHECK-MASSV %s +// RUN: %clang -### -c -fveclib=Darwin_libsystem_m %s 2>&1 | FileCheck --check-prefix=CHECK-DARWIN_LIBSYSTEM_M %s +// RUN: %clang -### -c --target=aarch64 -fveclib=SLEEF %s 2>&1 | FileCheck --check-prefix=CHECK-SLEEF %s +// RUN: %clang -### -c --target=aarch64 -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-ARMPL %s +// RUN: not %clang -c -fveclib=something %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID %s // CHECK-NOLIB: "-fveclib=none" // CHECK-ACCELERATE: "-fveclib=Accelerate" @@ -17,10 +17,10 @@ // CHECK-INVALID: error: invalid value 'something' in '-fveclib=something' -// RUN: not %clang --target=x86-none-none -c -fveclib=SLEEF %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s -// RUN: not %clang --target=x86-none-none -c -fveclib=ArmPL %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s -// RUN: not %clang --target=aarch64-none-none -c -fveclib=LIBMVEC-X86 %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s -// RUN: not %clang --target=aarch64-none-none -c -fveclib=SVML %s 2>&1 | FileCheck -check-prefix CHECK-ERROR %s +// RUN: not %clang --target=x86 -c -fveclib=SLEEF %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: not %clang --target=x86 -c -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: not %clang --target=aarch64 -c -fveclib=LIBMVEC-X86 %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: not %clang --target=aarch64 -c -fveclib=SVML %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s // CHECK-ERROR: unsupported option {{.*}} for target // RUN: %clang -fveclib=Accelerate %s -target arm64-apple-ios8.0.0 -### 2>&1 | FileCheck --check-prefix=CHECK-LINK %s @@ -35,17 +35,17 @@ /* Verify that the correct vector library is passed to LTO flags. */ -// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=LIBMVEC -flto %s 2>&1 | FileCheck -check-prefix CHECK-LTO-LIBMVEC %s +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=LIBMVEC -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-LIBMVEC %s // CHECK-LTO-LIBMVEC: "-plugin-opt=-vector-library=LIBMVEC-X86" -// RUN: %clang -### --target=powerpc64-unknown-linux-gnu -fveclib=MASSV -flto %s 2>&1 | FileCheck -check-prefix CHECK-LTO-MASSV %s +// RUN: %clang -### --target=powerpc64-unknown-linux-gnu -fveclib=MASSV -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-MASSV %s // CHECK-LTO-MASSV: "-plugin-opt=-vector-library=MASSV" -// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=SVML -flto %s 2>&1 | FileCheck -check-prefix CHECK-LTO-SVML %s +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=SVML -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-SVML %s // CHECK-LTO-SVML: "-plugin-opt=-vector-library=SVML" -// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=SLEEF -flto %s 2>&1 | FileCheck -check-prefix CHECK-LTO-SLEEF %s +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=SLEEF -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-SLEEF %s // CHECK-LTO-SLEEF: "-plugin-opt=-vector-library=sleefgnuabi" -// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -flto %s 2>&1 | FileCheck -check-prefix CHECK-LTO-ARMPL %s +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-ARMPL %s // CHECK-LTO-ARMPL: "-plugin-opt=-vector-library=ArmPL" diff --git a/clang/test/Driver/loongarch-mlasx-error.c b/clang/test/Driver/loongarch-mlasx-error.c index e66f277f7c292..1d88f0f1a7c63 100644 --- a/clang/test/Driver/loongarch-mlasx-error.c +++ b/clang/test/Driver/loongarch-mlasx-error.c @@ -11,5 +11,5 @@ // RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -mno-lsx 2>&1 \ // RUN: FileCheck --check-prefix=ERROR_LASX_FPU128 %s -// ERROR_LASX_FPU64: error: wrong fpu width; LASX depends on 64-bit FPU. -// ERROR_LASX_FPU128: error: invalid option combination; LASX depends on LSX. +// ERROR_LASX_FPU64: error: wrong fpu width; LASX depends on 64-bit FPU +// ERROR_LASX_FPU128: error: invalid option combination; LASX depends on LSX diff --git a/clang/test/Driver/loongarch-mlsx-error.c b/clang/test/Driver/loongarch-mlsx-error.c index bd6b8e2718bf6..db1f6fb2e5a0e 100644 --- a/clang/test/Driver/loongarch-mlsx-error.c +++ b/clang/test/Driver/loongarch-mlsx-error.c @@ -9,4 +9,4 @@ // RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlsx -mfpu=none 2>&1 \ // RUN: FileCheck --check-prefix=ERROR_LSX_FPU64 %s -// ERROR_LSX_FPU64: error: wrong fpu width; LSX depends on 64-bit FPU. +// ERROR_LSX_FPU64: error: wrong fpu width; LSX depends on 64-bit FPU diff --git a/clang/test/Driver/ms-define-stdc.c b/clang/test/Driver/ms-define-stdc.c new file mode 100644 index 0000000000000..d5e873d21a76b --- /dev/null +++ b/clang/test/Driver/ms-define-stdc.c @@ -0,0 +1,11 @@ +// Note: %s must be preceded by --, otherwise it may be interpreted as a +// command-line option, e.g. on Mac where %s is commonly under /Users. +// +// Note: see also cl-zc.cpp + +// RUN: %clang_cl /TC /dev/null /E -Xclang -dM /Zc:__STDC__- 2>&1 | FileCheck %s --check-prefix=ZCSTDCIGNORED +// ZCSTDCIGNORED-NOT: #define __STDC__ 1 +// ZCSTDCIGNORED: argument unused during compilation + +// RUN: not %clang -Xclang -fno-ms-define-stdc %s 2>&1 | FileCheck %s --check-prefix="NOARG" +// NOARG: error: unknown argument: '-fno-ms-define-stdc' diff --git a/clang/test/Driver/openmp-offload-infer.c b/clang/test/Driver/openmp-offload-infer.c index 50333293eb7db..388860abc01ad 100644 --- a/clang/test/Driver/openmp-offload-infer.c +++ b/clang/test/Driver/openmp-offload-infer.c @@ -43,7 +43,7 @@ // RUN: --offload-arch=sm_70 --offload-arch=gfx908 --offload-arch=skylake \ // RUN: -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-FAILED -// CHECK-FAILED: error: failed to deduce triple for target architecture 'skylake'; specify the triple using '-fopenmp-targets' and '-Xopenmp-target' instead. +// CHECK-FAILED: error: failed to deduce triple for target architecture 'skylake'; specify the triple using '-fopenmp-targets' and '-Xopenmp-target' instead // RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-bindings -fopenmp=libomp \ // RUN: --offload-arch=sm_70 --offload-arch=gfx908 -fno-openmp \ diff --git a/clang/test/Driver/openmp-system-arch.c b/clang/test/Driver/openmp-system-arch.c index 4e024e6b11d1b..a48c1e76fa758 100644 --- a/clang/test/Driver/openmp-system-arch.c +++ b/clang/test/Driver/openmp-system-arch.c @@ -31,7 +31,7 @@ // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -nogpulib -fopenmp=libomp --offload-arch= \ // RUN: --nvptx-arch-tool=%t/nvptx_arch_empty --amdgpu-arch-tool=%t/amdgpu_arch_empty %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO-OUTPUT-ERROR -// NO-OUTPUT-ERROR: error: failed to deduce triple for target architecture 'native'; specify the triple using '-fopenmp-targets' and '-Xopenmp-target' instead. +// NO-OUTPUT-ERROR: error: failed to deduce triple for target architecture 'native'; specify the triple using '-fopenmp-targets' and '-Xopenmp-target' instead // case when amdgpu-arch succeeds. // RUN: %clang -### --target=x86_64-unknown-linux-gnu -nogpulib -fopenmp=libomp --offload-arch=native \ diff --git a/clang/test/Driver/tocdata-cc1.c b/clang/test/Driver/tocdata-cc1.c index fe0d97ea02db1..e00383deecef8 100644 --- a/clang/test/Driver/tocdata-cc1.c +++ b/clang/test/Driver/tocdata-cc1.c @@ -1,16 +1,13 @@ // RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mcmodel=medium -mtocdata %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: | FileCheck %s // RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mcmodel=large -mtocdata %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: | FileCheck %s // RUN: %clang -### --target=powerpc-ibm-aix-xcoff -mtocdata %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-TOC %s +// RUN: | FileCheck %s // RUN: %clang -### --target=powerpc64-ibm-aix-xcoff -mcmodel=medium -mtocdata %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: | FileCheck %s // RUN: %clang -### --target=powerpc64-ibm-aix-xcoff -mcmodel=large -mtocdata %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-NOTOC %s +// RUN: | FileCheck %s // RUN: %clang -### --target=powerpc64-ibm-aix-xcoff -mtocdata %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHECK-TOC %s -// CHECK-NOTOC: warning: ignoring '-mtocdata' as it is only supported for -mcmodel=small -// CHECK-NOTOC-NOT: "-cc1"{{.*}}" "-mtocdata" -// CHECK-TOC: "-cc1"{{.*}}" "-mtocdata" -// CHECK-TOC-NOT: warning: ignoring '-mtocdata' as it is only supported for -mcmodel=small +// RUN: | FileCheck %s +// CHECK: "-cc1"{{.*}}" "-mtocdata" diff --git a/clang/test/Driver/x-args.c b/clang/test/Driver/x-args.c index 17bb5d99404da..06c9c7a461565 100644 --- a/clang/test/Driver/x-args.c +++ b/clang/test/Driver/x-args.c @@ -6,6 +6,4 @@ // RUN: %clang -fsyntax-only %s -xc %s -xc++ -fsyntax-only 2>&1 | FileCheck %s // CHECK: '-x c++' after last input file has no effect -// RUN: not %clang_cl /WX /clang:-xc /clang:-E /clang:-dM -- %s 2>&1 | FileCheck --implicit-check-not="error:" -check-prefix=CL %s -// RUN: not %clang_cl /TC /WX /clang:-xc /clang:-E /clang:-dM -- %s 2>&1 | FileCheck --implicit-check-not="error:" -check-prefix=CL %s -// CL: error: unsupported option '-x c'; did you mean '/TC' or '/TP'? +// RUN: %clang_cl -fsyntax-only /WX -xc++ -- %s diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 25f8f66bc3213..1d5f001c23fcc 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -21,10 +21,10 @@ // SSE4-AES: "-target-feature" "+sse4.2" "-target-feature" "+aes" // NO-SSE4-AES: "-target-feature" "-sse4.1" "-target-feature" "-aes" -// RUN: %clang --target=i386 -march=i386 -mavx -mavx2 -mavx512f -mavx512cd -mavx512er -mavx512pf -mavx512dq -mavx512bw -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma %s -### 2>&1 | FileCheck -check-prefix=AVX %s -// RUN: %clang --target=i386 -march=i386 -mno-avx -mno-avx2 -mno-avx512f -mno-avx512cd -mno-avx512er -mno-avx512pf -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512vbmi -mno-avx512vbmi2 -mno-avx512ifma %s -### 2>&1 | FileCheck -check-prefix=NO-AVX %s -// AVX: "-target-feature" "+avx" "-target-feature" "+avx2" "-target-feature" "+avx512f" "-target-feature" "+avx512cd" "-target-feature" "+avx512er" "-target-feature" "+avx512pf" "-target-feature" "+avx512dq" "-target-feature" "+avx512bw" "-target-feature" "+avx512vl" "-target-feature" "+avx512vbmi" "-target-feature" "+avx512vbmi2" "-target-feature" "+avx512ifma" -// NO-AVX: "-target-feature" "-avx" "-target-feature" "-avx2" "-target-feature" "-avx512f" "-target-feature" "-avx512cd" "-target-feature" "-avx512er" "-target-feature" "-avx512pf" "-target-feature" "-avx512dq" "-target-feature" "-avx512bw" "-target-feature" "-avx512vl" "-target-feature" "-avx512vbmi" "-target-feature" "-avx512vbmi2" "-target-feature" "-avx512ifma" +// RUN: %clang --target=i386 -march=i386 -mavx -mavx2 -mavx512f -mavx512cd -mavx512dq -mavx512bw -mavx512vl -mavx512vbmi -mavx512vbmi2 -mavx512ifma %s -### 2>&1 | FileCheck -check-prefix=AVX %s +// RUN: %clang --target=i386 -march=i386 -mno-avx -mno-avx2 -mno-avx512f -mno-avx512cd -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512vbmi -mno-avx512vbmi2 -mno-avx512ifma %s -### 2>&1 | FileCheck -check-prefix=NO-AVX %s +// AVX: "-target-feature" "+avx" "-target-feature" "+avx2" "-target-feature" "+avx512f" "-target-feature" "+avx512cd" "-target-feature" "+avx512dq" "-target-feature" "+avx512bw" "-target-feature" "+avx512vl" "-target-feature" "+avx512vbmi" "-target-feature" "+avx512vbmi2" "-target-feature" "+avx512ifma" +// NO-AVX: "-target-feature" "-avx" "-target-feature" "-avx2" "-target-feature" "-avx512f" "-target-feature" "-avx512cd" "-target-feature" "-avx512dq" "-target-feature" "-avx512bw" "-target-feature" "-avx512vl" "-target-feature" "-avx512vbmi" "-target-feature" "-avx512vbmi2" "-target-feature" "-avx512ifma" // RUN: %clang --target=i386 -march=i386 -mpclmul -mrdrnd -mfsgsbase -mbmi -mbmi2 %s -### 2>&1 | FileCheck -check-prefix=BMI %s // RUN: %clang --target=i386 -march=i386 -mno-pclmul -mno-rdrnd -mno-fsgsbase -mno-bmi -mno-bmi2 %s -### 2>&1 | FileCheck -check-prefix=NO-BMI %s @@ -86,11 +86,6 @@ // SGX: "-target-feature" "+sgx" // NO-SGX: "-target-feature" "-sgx" -// RUN: %clang --target=i386 -march=i386 -mprefetchwt1 %s -### 2>&1 | FileCheck -check-prefix=PREFETCHWT1 %s -// RUN: %clang --target=i386 -march=i386 -mno-prefetchwt1 %s -### 2>&1 | FileCheck -check-prefix=NO-PREFETCHWT1 %s -// PREFETCHWT1: "-target-feature" "+prefetchwt1" -// NO-PREFETCHWT1: "-target-feature" "-prefetchwt1" - // RUN: %clang --target=i386 -march=i386 -mprefetchi %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PREFETCHI %s // RUN: %clang --target=i386 -march=i386 -mno-prefetchi %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-PREFETCHI %s // PREFETCHI: "-target-feature" "+prefetchi" diff --git a/clang/test/ExtractAPI/non_type_template.cpp b/clang/test/ExtractAPI/non_type_template.cpp index 4e65eb790ca11..85f38e39c82bc 100644 --- a/clang/test/ExtractAPI/non_type_template.cpp +++ b/clang/test/ExtractAPI/non_type_template.cpp @@ -310,4 +310,48 @@ NestedTemplateTemplateParamPack var; // VAR-NEXT: } // VAR-NEXT: ] +template +class TypeContainer { + public: + // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TYPE + typedef Foo Type; +// TYPE-LABEL: "!testLabel": "c:non_type_template.cpp@ST>1#T@TypeContainer@T@Type", +// TYPE: "declarationFragments": [ +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "keyword", +// TYPE-NEXT: "spelling": "typedef" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": " " +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "typeIdentifier", +// TYPE-NEXT: "preciseIdentifier": "c:@ST>2#T#NI@Foo", +// TYPE-NEXT: "spelling": "Foo" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": "<" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "typeIdentifier", +// TYPE-NEXT: "preciseIdentifier": "c:t0.0", +// TYPE-NEXT: "spelling": "T" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": "> " +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "identifier", +// TYPE-NEXT: "spelling": "Type" +// TYPE-NEXT: }, +// TYPE-NEXT: { +// TYPE-NEXT: "kind": "text", +// TYPE-NEXT: "spelling": ";" +// TYPE-NEXT: } +// TYPE-NEXT: ] +}; + // expected-no-diagnostics diff --git a/clang/test/Frontend/optimization-remark-options.c b/clang/test/Frontend/optimization-remark-options.c index 96e480d140be8..357273a650635 100644 --- a/clang/test/Frontend/optimization-remark-options.c +++ b/clang/test/Frontend/optimization-remark-options.c @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target // RUN: %clang -O1 -fvectorize -target x86_64-unknown-unknown -mllvm -vectorize-memory-check-threshold=8 -Rpass-analysis=loop-vectorize -emit-llvm -S %s -o - 2>&1 | FileCheck %s -// CHECK: {{.*}}:10:11: remark: loop not vectorized: cannot prove it is safe to reorder floating-point operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop or by providing the compiler option '-ffast-math'. +// CHECK: {{.*}}:10:11: remark: loop not vectorized: cannot prove it is safe to reorder floating-point operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop or by providing the compiler option '-ffast-math' double foo(int N) { double v = 0.0; @@ -12,7 +12,7 @@ double foo(int N) { return v; } -// CHECK: {{.*}}:18:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied! +// CHECK: {{.*}}:18:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop; if the arrays will always be independent, specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments -- erroneous results will occur if these options are incorrectly applied void foo2(int *dw, int *uw, int *A, int *B, int *C, int *D, int N) { for (long i = 0; i < N; i++) { diff --git a/clang/test/Frontend/x86-target-cpu.c b/clang/test/Frontend/x86-target-cpu.c index 6b99b2c8574ae..6c8502ac2c21e 100644 --- a/clang/test/Frontend/x86-target-cpu.c +++ b/clang/test/Frontend/x86-target-cpu.c @@ -15,14 +15,8 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu cannonlake -verify %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu icelake-client -verify %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu icelake-server -verify %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knl -verify=knl %s -// knl-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// knl-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// knl-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knm -verify=knm %s -// knm-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// knm-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} -// knm-warning@*:* {{KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.}} +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knl -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu knm -verify %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu bonnell -verify %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu silvermont -verify %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu k8 -verify %s diff --git a/clang/test/InstallAPI/binary-attributes.test b/clang/test/InstallAPI/binary-attributes.test index b28e99f644546..fd9ff12998a34 100644 --- a/clang/test/InstallAPI/binary-attributes.test +++ b/clang/test/InstallAPI/binary-attributes.test @@ -30,13 +30,13 @@ ; RUN: -install_name /System/Library/Frameworks/Simple.framework/Versions/A/Simple \ ; RUN: -current_version 1.2.3 -compatibility_version 1 -fapplication-extension \ ; RUN: -o tmp.tbd --verify-against=%t/Simple 2>&1 | FileCheck -check-prefix=APPEXTSAFE %s -; APPEXTSAFE: error: ApplicationExtensionSafe flag does not match: 'true' (provided) vs 'false' (found) +; APPEXTSAFE: error: the ApplicationExtensionSafe flag does not match: 'true' (provided) vs 'false' (found) ; RUN: not clang-installapi -target x86_64-apple-macos10.12 \ ; RUN: -install_name /System/Library/Frameworks/Simple.framework/Versions/A/Simple \ ; RUN: -current_version 1.2.3 -compatibility_version 1 -not_for_dyld_shared_cache \ ; RUN: -o tmp.tbd --verify-against=%t/Simple 2>&1 | FileCheck -check-prefix=SHARED_CACHE %s -; SHARED_CACHE: error: NotForDyldSharedCache flag does not match: 'true' (provided) vs 'false' (found) +; SHARED_CACHE: error: the NotForDyldSharedCache flag does not match: 'true' (provided) vs 'false' (found) ; RUN: not clang-installapi -target x86_64-apple-macos10.12 \ ; RUN: -install_name /System/Library/Frameworks/Simple.framework/Versions/A/Simple \ diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index 41550cf02aa39..4c2aa3ae2c544 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -1,17 +1,17 @@ // RUN: %clang_cc1 -std=c++98 -fcxx-exceptions -verify %s // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -verify %s -// RUN: %clang_cc1 -std=c++14 -fcxx-exceptions -fsized-deallocation -verify %s -// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -verify %s -// RUN: %clang_cc1 -std=c++20 -fcxx-exceptions -fsized-deallocation -verify %s -// RUN: %clang_cc1 -std=c++23 -fcxx-exceptions -fsized-deallocation -verify %s -// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fsized-deallocation -verify %s +// RUN: %clang_cc1 -std=c++14 -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -std=c++20 -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -std=c++23 -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify %s // -// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -fno-relaxed-template-template-args -DNO_RELAXED_TEMPLATE_TEMPLATE_ARGS=1 -verify %s -// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -DCONCEPTS_TS=1 -verify %s -// RUN: %clang_cc1 -std=c++14 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation -// RUN: %clang_cc1 -std=c++14 -fchar8_t -DNO_EXCEPTIONS -DCHAR8_T -verify -fsized-deallocation %s -// RUN: %clang_cc1 -std=c++2a -fno-char8_t -DNO_EXCEPTIONS -DNO_CHAR8_T -verify -fsized-deallocation %s +// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fno-relaxed-template-template-args -DNO_RELAXED_TEMPLATE_TEMPLATE_ARGS=1 -verify %s +// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -DCONCEPTS_TS=1 -verify %s +// RUN: %clang_cc1 -std=c++14 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS +// RUN: %clang_cc1 -std=c++14 -fchar8_t -DNO_EXCEPTIONS -DCHAR8_T -verify %s +// RUN: %clang_cc1 -std=c++2a -fno-char8_t -DNO_EXCEPTIONS -DNO_CHAR8_T -verify %s // expected-no-diagnostics diff --git a/clang/test/Misc/diag-template-diffing.cpp b/clang/test/Misc/diag-template-diffing-cxx11.cpp similarity index 100% rename from clang/test/Misc/diag-template-diffing.cpp rename to clang/test/Misc/diag-template-diffing-cxx11.cpp diff --git a/clang/test/Misc/diag-template-diffing-cxx26.cpp b/clang/test/Misc/diag-template-diffing-cxx26.cpp new file mode 100644 index 0000000000000..2b6dd86a9885d --- /dev/null +++ b/clang/test/Misc/diag-template-diffing-cxx26.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fsyntax-only %s -std=c++26 -verify=expected,notree +// RUN: %clang_cc1 -fsyntax-only %s -std=c++26 -fno-elide-type -verify=expected,notree +// RUN: %clang_cc1 -fsyntax-only %s -std=c++26 -fdiagnostics-show-template-tree -verify=expected,tree +// RUN: %clang_cc1 -fsyntax-only %s -std=c++26 -fno-elide-type -fdiagnostics-show-template-tree -verify=expected,tree + +namespace GH93068 { + int n[2]; + + template struct A {}; // #A + + namespace t1 { + // notree-error@#1 {{no viable conversion from 'A<0>' to 'A'}} + + /* tree-error@#1 {{no viable conversion + A< + [0 != n + 1]>}}*/ + + A v1 = A<0>(); // #1 + // expected-note@#A {{no known conversion from 'A<0>' to 'const A<&n[1]> &' for 1st argument}} + // expected-note@#A {{no known conversion from 'A<0>' to 'A<&n[1]> &&' for 1st argument}} + + // notree-error@#2 {{no viable conversion from 'A' to 'A'}} + /* tree-error@#2 {{no viable conversion + A< + [n != n + 1]>}}*/ + + A v2 = A(); // #2 + // expected-note@#A {{no known conversion from 'A' to 'const A<&n[1]> &' for 1st argument}} + // expected-note@#A {{no known conversion from 'A' to 'A<&n[1]> &&' for 1st argument}} + } // namespace t1 + + namespace t2 { + A v1; + A v2; + + // notree-note@#A {{no known conversion from 'A' to 'const A<(no argument)>' for 1st argument}} + // notree-note@#A {{no known conversion from 'A' to 'A<(no argument)>' for 1st argument}} + + /* tree-note@#A {{no known conversion from argument type to parameter type for 1st argument + [(no qualifiers) != const] A< + [n != (no argument)]>}}*/ + + /* tree-note@#A {{no known conversion from argument type to parameter type for 1st argument + A< + [n != (no argument)]>}}*/ + + void f() { v2 = v1; } // expected-error {{no viable overloaded '='}} + } // namespace t2 +} // namespace GH93068 diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index fd0e6d71baa80..99732694f72a5 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -63,7 +63,6 @@ // CHECK-NEXT: CoroOnlyDestroyWhenComplete (SubjectMatchRule_record) // CHECK-NEXT: CoroReturnType (SubjectMatchRule_record) // CHECK-NEXT: CoroWrapper (SubjectMatchRule_function) -// CHECK-NEXT: CountedBy (SubjectMatchRule_field) // CHECK-NEXT: DLLExport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface) // CHECK-NEXT: DLLImport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface) // CHECK-NEXT: Destructor (SubjectMatchRule_function) diff --git a/clang/test/Modules/implicit-module-remap.cpp b/clang/test/Modules/implicit-module-remap.cpp new file mode 100644 index 0000000000000..47927b9694016 --- /dev/null +++ b/clang/test/Modules/implicit-module-remap.cpp @@ -0,0 +1,21 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t +// +// RUN: %clang_cc1 -fmodules -fmodule-map-file=module.modulemap -fmodules-cache-path=%t -remap-file "test.cpp;%t/test.cpp" %t/test.cpp + +//--- a.h +#define FOO + +//--- module.modulemap +module a { + header "a.h" +} + +//--- test.cpp +#include "a.h" + +#ifndef FOO +#error foo +#endif + diff --git a/clang/test/OpenMP/assumes_codegen.cpp b/clang/test/OpenMP/assumes_codegen.cpp index 4a2518a51ec34..4206e5a9caab7 100644 --- a/clang/test/OpenMP/assumes_codegen.cpp +++ b/clang/test/OpenMP/assumes_codegen.cpp @@ -67,46 +67,46 @@ int lambda_outer() { } #pragma omp end assumes -// AST: void foo() __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) { -// AST-NEXT: } -// AST-NEXT: class BAR { -// AST-NEXT: public: -// AST-NEXT: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAR() { -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void bar1() { -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) static void bar2() { -// AST-NEXT: } -// AST-NEXT: }; -// AST-NEXT: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void bar() { -// AST-NEXT: BAR b; -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz(); -// AST-NEXT: template class BAZ { -// AST-NEXT: public: -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAZ() { -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz1() { -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) static void baz2() { -// AST-NEXT: } -// AST-NEXT: }; -// AST-NEXT: template<> class BAZ { -// AST-NEXT: public: -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAZ() { -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz1(); -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) static void baz2(); -// AST-NEXT: }; -// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz() { -// AST-NEXT: BAZ b; -// AST-NEXT: } -// AST-NEXT: __attribute__((assume("ompx_lambda_assumption"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) int lambda_outer() { -// AST-NEXT: auto lambda_inner = []() { -// AST-NEXT: return 42; -// AST-NEXT: }; -// AST-NEXT: return lambda_inner(); -// AST-NEXT: } +// AST{LITERAL}: void foo() [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: class BAR { +// AST-NEXT{LITERAL}: public: +// AST-NEXT{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] BAR() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] void bar1() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] static void bar2() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: }; +// AST-NEXT{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] void bar() { +// AST-NEXT{LITERAL}: BAR b; +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] void baz(); +// AST-NEXT{LITERAL}: template class BAZ { +// AST-NEXT{LITERAL}: public: +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] BAZ() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] void baz1() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] static void baz2() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: }; +// AST-NEXT{LITERAL}: template<> class BAZ { +// AST-NEXT{LITERAL}: public: +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] BAZ() { +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] void baz1(); +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] static void baz2(); +// AST-NEXT{LITERAL}: }; +// AST-NEXT{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] void baz() { +// AST-NEXT{LITERAL}: BAZ b; +// AST-NEXT{LITERAL}: } +// AST-NEXT{LITERAL}: [[omp::assume("ompx_lambda_assumption")]] [[omp::assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses")]] [[omp::assume("omp_no_openmp")]] int lambda_outer() { +// AST-NEXT{LITERAL}: auto lambda_inner = []() { +// AST-NEXT{LITERAL}: return 42; +// AST-NEXT{LITERAL}: }; +// AST-NEXT{LITERAL}: return lambda_inner(); +// AST-NEXT{LITERAL}: } #endif diff --git a/clang/test/OpenMP/assumes_print.cpp b/clang/test/OpenMP/assumes_print.cpp index d8bdaaaf45180..9254c29ab8335 100644 --- a/clang/test/OpenMP/assumes_print.cpp +++ b/clang/test/OpenMP/assumes_print.cpp @@ -37,8 +37,8 @@ void baz() { } #pragma omp end assumes -// CHECK: void foo() __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) -// CHECK: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void bar() -// CHECK: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void baz() +// CHECK{LITERAL}: void foo() [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp")]] +// CHECK{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp")]] void bar() +// CHECK{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp")]] void baz() #endif diff --git a/clang/test/OpenMP/assumes_template_print.cpp b/clang/test/OpenMP/assumes_template_print.cpp index 614138b2ee0bb..f8857ffadf786 100644 --- a/clang/test/OpenMP/assumes_template_print.cpp +++ b/clang/test/OpenMP/assumes_template_print.cpp @@ -17,7 +17,7 @@ template struct S { int a; // CHECK: template struct S { -// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { +// CHECK{LITERAL}: void foo() [[omp::assume("ompx_global_assumption")]] { void foo() { #pragma omp parallel {} @@ -25,15 +25,15 @@ struct S { }; // CHECK: template<> struct S { -// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { +// CHECK{LITERAL}: void foo() [[omp::assume("ompx_global_assumption")]] { #pragma omp begin assumes no_openmp -// CHECK: __attribute__((assume("omp_no_openmp"))) void S_with_assumes_no_call() __attribute__((assume("ompx_global_assumption"))) { +// CHECK{LITERAL}: [[omp::assume("omp_no_openmp")]] void S_with_assumes_no_call() [[omp::assume("ompx_global_assumption")]] { void S_with_assumes_no_call() { S s; s.a = 0; } -// CHECK: __attribute__((assume("omp_no_openmp"))) void S_with_assumes_call() __attribute__((assume("ompx_global_assumption"))) { +// CHECK{LITERAL}: [[omp::assume("omp_no_openmp")]] void S_with_assumes_call() [[omp::assume("ompx_global_assumption")]] { void S_with_assumes_call() { S s; s.a = 0; @@ -42,7 +42,7 @@ void S_with_assumes_call() { } #pragma omp end assumes -// CHECK: void S_without_assumes() __attribute__((assume("ompx_global_assumption"))) { +// CHECK{LITERAL}: void S_without_assumes() [[omp::assume("ompx_global_assumption")]] { void S_without_assumes() { S s; s.foo(); @@ -54,7 +54,7 @@ void S_without_assumes() { template struct P { // CHECK: template struct P { -// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() { +// CHECK{LITERAL}: [[omp::assume("ompx_global_assumption")]] void foo() { int a; void foo() { #pragma omp parallel @@ -65,21 +65,21 @@ struct P { // TODO: Avoid the duplication here: // CHECK: template<> struct P { -// CHECK: __attribute__((assume("ompx_global_assumption"))) __attribute__((assume("ompx_global_assumption"))) void foo() { +// CHECK{LITERAL}: [[omp::assume("ompx_global_assumption")]] [[omp::assume("ompx_global_assumption")]] void foo() { -// CHECK: __attribute__((assume("ompx_global_assumption"))) void P_without_assumes() { +// CHECK{LITERAL}: [[omp::assume("ompx_global_assumption")]] void P_without_assumes() { void P_without_assumes() { P p; p.foo(); } #pragma omp begin assumes no_openmp -// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void P_with_assumes_no_call() { +// CHECK{LITERAL}: [[omp::assume("omp_no_openmp")]] [[omp::assume("ompx_global_assumption")]] void P_with_assumes_no_call() { void P_with_assumes_no_call() { P p; p.a = 0; } -// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void P_with_assumes_call() { +// CHECK{LITERAL}: [[omp::assume("omp_no_openmp")]] [[omp::assume("ompx_global_assumption")]] void P_with_assumes_call() { void P_with_assumes_call() { P p; p.a = 0; diff --git a/clang/test/OpenMP/atomic_messages.c b/clang/test/OpenMP/atomic_messages.c index 9f6662a9e136a..f4e7db52494af 100644 --- a/clang/test/OpenMP/atomic_messages.c +++ b/clang/test/OpenMP/atomic_messages.c @@ -405,67 +405,67 @@ void compare(void) { int x = 0; int d = 0; int e = 0; -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected compound statement}} #pragma omp atomic compare {} -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected exactly one expression statement}} #pragma omp atomic compare { x = d; x = e; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare { x += d; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare { bbar(); } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected conditional operator}} #pragma omp atomic compare { x = d; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect binary operator in conditional expression}} #pragma omp atomic compare { x = ffoo() ? e : x; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect '<', '>' or '==' as order operator}} #pragma omp atomic compare { x = x >= e ? e : x; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'}} #pragma omp atomic compare { x = d > e ? e : x; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect result value to be at false expression}} #pragma omp atomic compare { x = d > x ? e : d; } -// omp51-error@+4 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+4 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+3 {{expect binary operator in conditional expression}} #pragma omp atomic compare { if (foo()) x = d; } -// omp51-error@+4 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+4 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+3 {{expect '<', '>' or '==' as order operator}} #pragma omp atomic compare { if (x >= d) x = d; } -// omp51-error@+4 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+4 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+3 {{expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'}} #pragma omp atomic compare { if (e > d) x = d; } -// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected exactly one expression statement}} #pragma omp atomic compare { @@ -473,7 +473,7 @@ void compare(void) { x = e; d = e; } -// omp51-error@+7 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+7 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+6 {{unexpected 'else' statement}} #pragma omp atomic compare { @@ -491,61 +491,61 @@ void compare_capture(void) { int v = 0; int r = 0; float dr = 0.0; -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected compound statement}} #pragma omp atomic compare capture if (x == e) {} -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected exactly one expression statement}} #pragma omp atomic compare capture if (x == e) { x = d; v = x; } -// omp51-error@+4 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+4 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+3 {{expected assignment statement}} #pragma omp atomic compare capture if (x == e) { bbar(); } -// omp51-error@+4 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+4 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+3 {{expected assignment statement}} #pragma omp atomic compare capture if (x == e) { x += d; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect binary operator in conditional expression}} #pragma omp atomic compare capture if (ffoo()) { x = d; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect '==' operator}} #pragma omp atomic compare capture if (x > e) { x = d; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'}} #pragma omp atomic compare capture if (d == e) { x = d; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect 'else' statement}} #pragma omp atomic compare capture if (x == e) { x = d; } -// omp51-error@+5 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+5 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+4 {{expected compound statement}} #pragma omp atomic compare capture if (x == e) { x = d; } else { } -// omp51-error@+5 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+5 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+4 {{expected exactly one expression statement}} #pragma omp atomic compare capture if (x == e) { @@ -554,7 +554,7 @@ void compare_capture(void) { v = x; d = e; } -// omp51-error@+6 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+6 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+5 {{expected assignment statement}} #pragma omp atomic compare capture if (x == e) { @@ -562,7 +562,7 @@ void compare_capture(void) { } else { bbar(); } -// omp51-error@+6 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+6 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+5 {{expected assignment statement}} #pragma omp atomic compare capture if (x == e) { @@ -570,7 +570,7 @@ void compare_capture(void) { } else { v += x; } -// omp51-error@+6 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+6 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+5 {{expect an assignment statement 'v = x'}} #pragma omp atomic compare capture if (x == e) { @@ -578,35 +578,35 @@ void compare_capture(void) { } else { v = d; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected compound statement}} #pragma omp atomic compare capture {} -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect a compound statement}} #pragma omp atomic compare capture x = x > e ? e : x; -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect a 'if' statement}} #pragma omp atomic compare capture { x = x > e ? e : x; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect a form 'r = x == e; if (r) ...'}} #pragma omp atomic compare capture { r = x == e; if (x == d) { x = e; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { r = x == e; if (r) { bbar(); } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { r = x == e; if (r) { x += d; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected compound statement}} #pragma omp atomic compare capture { r = x == e; if (r) {} } -// omp51-error@+5 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+5 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+4 {{expected exactly one expression statement}} #pragma omp atomic compare capture { @@ -616,19 +616,19 @@ void compare_capture(void) { v = x; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect '==' operator}} #pragma omp atomic compare capture { r = x > e; if (r) { x = d; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'}} #pragma omp atomic compare capture { r = d == e; if (r) { x = d; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected compound statement}} #pragma omp atomic compare capture { r = x == e; if (r) { x = d; } else {} } -// omp51-error@+7 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+7 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+6 {{expected exactly one expression statement}} #pragma omp atomic compare capture { @@ -640,40 +640,40 @@ void compare_capture(void) { d = e; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { r = x == e; if (r) { x = d; } else { bbar(); } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { r = x == e; if (r) { x = d; } else { v += x; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect an assignment statement 'v = x'}} #pragma omp atomic compare capture { r = x == e; if (r) { x = d; } else { v = d; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { v += x; if (x == e) { x = d; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { if (x == e) { x = d; } v += x; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect an assignment statement 'v = x'}} #pragma omp atomic compare capture { v = d; if (x == e) { x = d; } } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect an assignment statement 'v = x'}} #pragma omp atomic compare capture { if (x == e) { x = d; } v = d; } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expected assignment statement}} #pragma omp atomic compare capture { v = x; bbar(); } -// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-error@+3 {{the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}', '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'}} // omp51-note@+2 {{expect integer value}} #pragma omp atomic compare capture { dr = x == e; if (dr) { x = d; } } diff --git a/clang/test/OpenMP/distribute_firstprivate_messages.cpp b/clang/test/OpenMP/distribute_firstprivate_messages.cpp index 30fa8be519ef2..f507c86b601f5 100644 --- a/clang/test/OpenMP/distribute_firstprivate_messages.cpp +++ b/clang/test/OpenMP/distribute_firstprivate_messages.cpp @@ -95,7 +95,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams - #pragma omp distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}} + #pragma omp distribute firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-error {{no matching constructor for initialization of 'S3'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams @@ -103,11 +103,11 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams - #pragma omp distribute firstprivate(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} + #pragma omp distribute firstprivate(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams - #pragma omp distribute firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} + #pragma omp distribute firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams diff --git a/clang/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp index 84d6337be34bb..4bed1fe2c3a3e 100644 --- a/clang/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp @@ -119,7 +119,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -129,7 +129,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -241,7 +241,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -256,12 +256,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(ca) // expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(ca) // expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -292,12 +292,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(m) // expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(m) // expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -329,13 +329,13 @@ int main(int argc, char **argv) { // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(g) firstprivate(g) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{Type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel diff --git a/clang/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp index f403922e14e8b..0a0962ef57c1d 100644 --- a/clang/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp @@ -119,7 +119,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -129,7 +129,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-warning 2 {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-warning 2 {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -228,7 +228,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -243,12 +243,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}} expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}} expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -279,12 +279,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -325,13 +325,13 @@ int main(int argc, char **argv) { // expected-error@+3 {{firstprivate variable cannot be lastprivate}} expected-note@+3 {{defined as firstprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute parallel for firstprivate(m) lastprivate(m) // expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for firstprivate(m) lastprivate(m) // expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{Type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); static int si; diff --git a/clang/test/OpenMP/distribute_parallel_for_private_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_private_messages.cpp index d25598e46f816..2e0e75096a26a 100644 --- a/clang/test/OpenMP/distribute_parallel_for_private_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_private_messages.cpp @@ -50,7 +50,7 @@ class S5 { #pragma omp target #pragma omp teams #pragma omp distribute parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp index 6b3d9da9a3a6e..864fb597214b9 100644 --- a/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_reduction_messages.cpp @@ -187,7 +187,7 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning 2 {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning 2 {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -232,7 +232,7 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} expected-warning 2 {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} expected-warning 2 {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -371,12 +371,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -386,12 +386,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -416,12 +416,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -437,12 +437,12 @@ int main(int argc, char **argv) { #pragma omp parallel private(k) #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp index 43bc6ad8e6372..0cb8c01625dbf 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp @@ -50,7 +50,7 @@ class S5 { #pragma omp target #pragma omp teams #pragma omp distribute parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp index 7c83e4c674c66..6dc6e777fb33d 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_shared_messages.cpp @@ -117,7 +117,7 @@ T tmain(T argc, S **argv) { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } @@ -131,14 +131,14 @@ T tmain(T argc, S **argv) { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared(ca) // expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared(ca) // expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } @@ -152,7 +152,7 @@ T tmain(T argc, S **argv) { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared(e, g) // expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared(e, g) // expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } @@ -291,7 +291,7 @@ int main(int argc, char **argv) { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared (a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } @@ -305,14 +305,14 @@ int main(int argc, char **argv) { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared(ca) // expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared(ca) // expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } @@ -326,7 +326,7 @@ int main(int argc, char **argv) { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd shared(e, g) // expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute parallel for simd shared(e, g) // expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for(int k = 0 ; k < n ; k++) { acc++; } diff --git a/clang/test/OpenMP/distribute_simd_firstprivate_messages.cpp b/clang/test/OpenMP/distribute_simd_firstprivate_messages.cpp index 43057fe5bacc5..bc1dfcfe7ab48 100644 --- a/clang/test/OpenMP/distribute_simd_firstprivate_messages.cpp +++ b/clang/test/OpenMP/distribute_simd_firstprivate_messages.cpp @@ -111,7 +111,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(z, a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(z, a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -121,7 +121,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -233,7 +233,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -248,12 +248,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(ca) // expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(ca) // expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -284,12 +284,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(m) // expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(m) // expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -321,13 +321,13 @@ int main(int argc, char **argv) { // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(g) firstprivate(g) //expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(g) firstprivate(g) //expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{Type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel diff --git a/clang/test/OpenMP/distribute_simd_lastprivate_messages.cpp b/clang/test/OpenMP/distribute_simd_lastprivate_messages.cpp index 7658288242ab3..379f575474984 100644 --- a/clang/test/OpenMP/distribute_simd_lastprivate_messages.cpp +++ b/clang/test/OpenMP/distribute_simd_lastprivate_messages.cpp @@ -120,7 +120,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -130,7 +130,7 @@ int foomain(int argc, char **argv) { ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-warning 2 {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(e, g) // expected-error 2 {{calling a private constructor of class 'S4'}} expected-warning 2 {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} for (int k = 0; k < argc; ++k) ++k; #pragma omp target @@ -229,7 +229,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be lastprivate}} expected-error 2 {{const-qualified variable cannot be lastprivate}} expected-error {{incomplete type 'S1' where a complete type is required}} expected-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -244,12 +244,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(ba) // expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(ba) // expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}} expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}} expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -280,12 +280,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(m) // expected-error {{'operator=' is a private member of 'S3'}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -326,13 +326,13 @@ int main(int argc, char **argv) { // expected-error@+3 {{firstprivate variable cannot be lastprivate}} expected-note@+3 {{defined as firstprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute simd firstprivate(m) lastprivate(m) // expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd firstprivate(m) lastprivate(m) // expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); // expected-error@+3 {{lastprivate variable cannot be firstprivate}} expected-note@+3 {{defined as lastprivate}} #pragma omp target #pragma omp teams -#pragma omp distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{Type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd lastprivate(n) firstprivate(n) // expected-error {{calling a private constructor of class 'S6'}} expected-warning {{type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); static int si; diff --git a/clang/test/OpenMP/distribute_simd_loop_messages.cpp b/clang/test/OpenMP/distribute_simd_loop_messages.cpp index 5a55f9569b8dc..e56c7dfbddab8 100644 --- a/clang/test/OpenMP/distribute_simd_loop_messages.cpp +++ b/clang/test/OpenMP/distribute_simd_loop_messages.cpp @@ -14,7 +14,7 @@ class S5 { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } @@ -490,7 +490,7 @@ int test_with_random_access_iterator() { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams @@ -501,41 +501,41 @@ int test_with_random_access_iterator() { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp distribute simd - for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp distribute simd - for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp distribute simd - for (GoodIter I(0); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(0); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp distribute simd - for (GoodIter I(1,2); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(1,2); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams #pragma omp distribute simd - for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams #pragma omp distribute simd - for (begin = GoodIter(1,2); begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = GoodIter(1,2); begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams @@ -546,7 +546,7 @@ int test_with_random_access_iterator() { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (begin = end; begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = end; begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams @@ -576,7 +576,7 @@ int test_with_random_access_iterator() { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams @@ -600,7 +600,7 @@ int test_with_random_access_iterator() { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (Iter0 I = begin0; I < end0; ++I) // expected-warning 2 {{Type 'Iter0' is not trivially copyable and not guaranteed to be mapped correctly}} + for (Iter0 I = begin0; I < end0; ++I) // expected-warning 2 {{type 'Iter0' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target @@ -608,7 +608,7 @@ int test_with_random_access_iterator() { // Initializer is constructor without params. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} #pragma omp distribute simd - for (Iter0 I; I < end0; ++I) // expected-warning {{Type 'Iter0' is not trivially copyable and not guaranteed to be mapped correctly}} + for (Iter0 I; I < end0; ++I) // expected-warning {{type 'Iter0' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; Iter1 begin1, end1; @@ -654,7 +654,7 @@ template class TC { // expected-note@+3 {{loop step is expected to be positive due to this condition}} // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} #pragma omp distribute simd - for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp distribute simd @@ -697,7 +697,7 @@ template int dotest_gt(IT begin, IT end) { #pragma omp target #pragma omp teams #pragma omp distribute simd - for (IT I = begin; I < end; I+=TC::step()) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I+=TC::step()) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } diff --git a/clang/test/OpenMP/distribute_simd_private_messages.cpp b/clang/test/OpenMP/distribute_simd_private_messages.cpp index 261a46ac6099b..8be71938e0fa7 100644 --- a/clang/test/OpenMP/distribute_simd_private_messages.cpp +++ b/clang/test/OpenMP/distribute_simd_private_messages.cpp @@ -50,7 +50,7 @@ class S5 { #pragma omp target #pragma omp teams #pragma omp distribute simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/distribute_simd_reduction_messages.cpp b/clang/test/OpenMP/distribute_simd_reduction_messages.cpp index d27360ac9b2cc..03b6ee5f4a257 100644 --- a/clang/test/OpenMP/distribute_simd_reduction_messages.cpp +++ b/clang/test/OpenMP/distribute_simd_reduction_messages.cpp @@ -187,7 +187,7 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning 2 {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}} expected-warning 2 {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning 2 {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -232,7 +232,7 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} expected-warning 2 {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} expected-warning 2 {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -376,12 +376,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-warning {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} +#pragma omp distribute simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} expected-warning {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-warning {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} +#pragma omp distribute simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-warning {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} expected-error {{incomplete type 'S1' where a complete type is required}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -391,12 +391,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd reduction(+ : ba) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{type 'const S2[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd reduction(* : ca) // expected-error {{const-qualified variable cannot be reduction}} expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -421,12 +421,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}}} +#pragma omp distribute simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} expected-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} expected-warning {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp distribute simd reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}} expected-warning {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; ++i) foo(); #pragma omp target @@ -440,7 +440,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #if __cplusplus < 201103L // < C++11 -// expected-warning@+5 {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +// expected-warning@+5 {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} #endif #pragma omp parallel private(k) #pragma omp target @@ -449,7 +449,7 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #if __cplusplus < 201103L // < C++11 -// expected-warning@+4 {{Type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} +// expected-warning@+4 {{type 'S3' is not trivially copyable and not guaranteed to be mapped correctly}} #endif #pragma omp target #pragma omp teams diff --git a/clang/test/OpenMP/reduction_implicit_map.cpp b/clang/test/OpenMP/reduction_implicit_map.cpp index 0f67cdc56ddcf..765e90bcba853 100644 --- a/clang/test/OpenMP/reduction_implicit_map.cpp +++ b/clang/test/OpenMP/reduction_implicit_map.cpp @@ -47,7 +47,7 @@ int bar() { S2 o[5]; //warnig "copyable and not guaranteed to be mapped correctly" and //implicit map generated. -#pragma omp target parallel reduction(+:o[0]) //expected-warning {{Type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target parallel reduction(+:o[0]) //expected-warning {{type 'S2' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 10; i++); double b[10][10][10]; //no error no implicit map generated, the map for b is generated but not diff --git a/clang/test/OpenMP/remarks_parallel_in_multiple_target_state_machines.c b/clang/test/OpenMP/remarks_parallel_in_multiple_target_state_machines.c index 2f829d2ad0945..1afedc6683f86 100644 --- a/clang/test/OpenMP/remarks_parallel_in_multiple_target_state_machines.c +++ b/clang/test/OpenMP/remarks_parallel_in_multiple_target_state_machines.c @@ -4,7 +4,7 @@ // host-no-diagnostics -void baz(void) __attribute__((assume("omp_no_openmp"))); +[[omp::assume("omp_no_openmp")]] void baz(void); void bar1(void) { #pragma omp parallel // #0 @@ -24,7 +24,7 @@ void foo1(void) { // all-remark@#2 {{Rewriting generic-mode kernel with a customized state machine. [OMP131]}} { - baz(); // all-remark {{Value has potential side effects preventing SPMD-mode execution. Add `__attribute__((assume("ompx_spmd_amenable")))` to the called function to override. [OMP121]}} + baz(); // all-remark {{Value has potential side effects preventing SPMD-mode execution. Add `[[omp::assume("ompx_spmd_amenable")]]` to the called function to override. [OMP121]}} #pragma omp parallel // #3 { } @@ -39,7 +39,7 @@ void foo2(void) { #pragma omp target teams // #5 // all-remark@#5 {{Rewriting generic-mode kernel with a customized state machine. [OMP131]}} { - baz(); // all-remark {{Value has potential side effects preventing SPMD-mode execution. Add `__attribute__((assume("ompx_spmd_amenable")))` to the called function to override. [OMP121]}} + baz(); // all-remark {{Value has potential side effects preventing SPMD-mode execution. Add `[[omp::assume("ompx_spmd_amenable")]]` to the called function to override. [OMP121]}} #pragma omp parallel // #6 { } @@ -57,7 +57,7 @@ void foo3(void) { #pragma omp target teams // #8 // all-remark@#8 {{Rewriting generic-mode kernel with a customized state machine. [OMP131]}} { - baz(); // all-remark {{Value has potential side effects preventing SPMD-mode execution. Add `__attribute__((assume("ompx_spmd_amenable")))` to the called function to override. [OMP121]}} + baz(); // all-remark {{Value has potential side effects preventing SPMD-mode execution. Add `[[omp::assume("ompx_spmd_amenable")]]` to the called function to override. [OMP121]}} #pragma omp parallel // #9 { } diff --git a/clang/test/OpenMP/remarks_parallel_in_target_state_machine.c b/clang/test/OpenMP/remarks_parallel_in_target_state_machine.c index c48a4b966077d..5ce8f1fa4046d 100644 --- a/clang/test/OpenMP/remarks_parallel_in_target_state_machine.c +++ b/clang/test/OpenMP/remarks_parallel_in_target_state_machine.c @@ -3,7 +3,7 @@ // host-no-diagnostics -void baz(void) __attribute__((assume("omp_no_openmp"))); +[[omp::assume("omp_no_openmp")]] void baz(void); void bar(void) { #pragma omp parallel // #1 \ @@ -16,7 +16,7 @@ void foo(void) { #pragma omp target teams // #2 // expected-remark@#2 {{Rewriting generic-mode kernel with a customized state machine. [OMP131]}} { - baz(); // expected-remark {{Value has potential side effects preventing SPMD-mode execution. Add `__attribute__((assume("ompx_spmd_amenable")))` to the called function to override. [OMP121]}} + baz(); // expected-remark {{Value has potential side effects preventing SPMD-mode execution. Add `[[omp::assume("ompx_spmd_amenable")]]` to the called function to override. [OMP121]}} #pragma omp parallel { } diff --git a/clang/test/OpenMP/requires_default_atomic_mem_order_messages.cpp b/clang/test/OpenMP/requires_default_atomic_mem_order_messages.cpp index 19f6ede043d85..5160fbbfb4a79 100644 --- a/clang/test/OpenMP/requires_default_atomic_mem_order_messages.cpp +++ b/clang/test/OpenMP/requires_default_atomic_mem_order_messages.cpp @@ -7,6 +7,6 @@ void foo2() { } #pragma omp requires atomic_default_mem_order(seq_cst) // expected-error {{'atomic' region encountered before requires directive with 'atomic_default_mem_order' clause}} expected-note 2 {{atomic_default_mem_order clause previously used here}} -#pragma omp requires atomic_default_mem_order(acq_rel) // expected-error {{'atomic' region encountered before requires directive with 'atomic_default_mem_order' clause}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} -#pragma omp requires atomic_default_mem_order(relaxed) // expected-error {{'atomic' region encountered before requires directive with 'atomic_default_mem_order' clause}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(acq_rel) // expected-error {{'atomic' region encountered before requires directive with 'atomic_default_mem_order' clause}} expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(relaxed) // expected-error {{'atomic' region encountered before requires directive with 'atomic_default_mem_order' clause}} expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} #pragma omp requires atomic_default_mem_order(release) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} diff --git a/clang/test/OpenMP/requires_messages.cpp b/clang/test/OpenMP/requires_messages.cpp index 10d311631b100..dbb2b317067b7 100644 --- a/clang/test/OpenMP/requires_messages.cpp +++ b/clang/test/OpenMP/requires_messages.cpp @@ -6,39 +6,39 @@ int a; #pragma omp requires unified_shared_memory // rev-note {{unified_shared_memory clause previously used here}} expected-note{{unified_shared_memory clause previously used here}} -#pragma omp requires unified_shared_memory, unified_shared_memory // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_shared_memory' clause}} +#pragma omp requires unified_shared_memory, unified_shared_memory // expected-error {{only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_shared_memory' clause}} -#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} +#pragma omp requires unified_address // expected-error {{only one unified_address clause can appear on a requires directive in a single translation unit}} -#pragma omp requires unified_address, unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_address' clause}} +#pragma omp requires unified_address, unified_address // expected-error {{only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_address' clause}} #ifdef OMP99 #pragma omp requires reverse_offload // rev-note {{reverse_offload clause previously used here}} rev-note {{reverse_offload clause previously used here}} -#pragma omp requires reverse_offload, reverse_offload // rev-error {{Only one reverse_offload clause can appear on a requires directive in a single translation unit}} rev-error {{directive '#pragma omp requires' cannot contain more than one 'reverse_offload' clause}} +#pragma omp requires reverse_offload, reverse_offload // rev-error {{only one reverse_offload clause can appear on a requires directive in a single translation unit}} rev-error {{directive '#pragma omp requires' cannot contain more than one 'reverse_offload' clause}} #endif #pragma omp requires dynamic_allocators // rev-note {{dynamic_allocators clause previously used here}} expected-note {{dynamic_allocators clause previously used here}} -#pragma omp requires dynamic_allocators, dynamic_allocators // expected-error {{Only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'dynamic_allocators' clause}} +#pragma omp requires dynamic_allocators, dynamic_allocators // expected-error {{only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'dynamic_allocators' clause}} #pragma omp requires atomic_default_mem_order(seq_cst) // rev-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} -#pragma omp requires atomic_default_mem_order(acq_rel) // expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(acq_rel) // expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} -#pragma omp requires atomic_default_mem_order(relaxed) // expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(relaxed) // expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} #pragma omp requires atomic_default_mem_order // expected-error {{expected '(' after 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} #pragma omp requires atomic_default_mem_order( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} -#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} #pragma omp requires atomic_default_mem_order(invalid_modifier) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} #pragma omp requires atomic_default_mem_order(shared) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} -#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} #pragma omp requires // expected-error {{expected at least one clause on '#pragma omp requires' directive}} @@ -46,18 +46,18 @@ int a; #pragma omp requires nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp requires'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} -#pragma omp requires unified_address, invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} +#pragma omp requires unified_address, invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{only one unified_address clause can appear on a requires directive in a single translation unit}} #pragma omp requires invalid_clause unified_address // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} #ifdef OMP99 -#pragma omp requires unified_shared_memory, unified_address, reverse_offload, dynamic_allocators, atomic_default_mem_order(seq_cst) // rev-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} rev-error{{Only one unified_address clause can appear on a requires directive in a single translation unit}} rev-error{{Only one reverse_offload clause can appear on a requires directive in a single translation unit}} rev-error{{Only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} rev-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} +#pragma omp requires unified_shared_memory, unified_address, reverse_offload, dynamic_allocators, atomic_default_mem_order(seq_cst) // rev-error {{only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} rev-error{{only one unified_address clause can appear on a requires directive in a single translation unit}} rev-error{{only one reverse_offload clause can appear on a requires directive in a single translation unit}} rev-error{{only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} rev-error {{only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} #endif namespace A { - #pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} + #pragma omp requires unified_address // expected-error {{only one unified_address clause can appear on a requires directive in a single translation unit}} namespace B { - #pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} + #pragma omp requires unified_address // expected-error {{only one unified_address clause can appear on a requires directive in a single translation unit}} } } diff --git a/clang/test/OpenMP/target_device_ancestor_messages.cpp b/clang/test/OpenMP/target_device_ancestor_messages.cpp index bc1d668d19143..e6705b369c709 100644 --- a/clang/test/OpenMP/target_device_ancestor_messages.cpp +++ b/clang/test/OpenMP/target_device_ancestor_messages.cpp @@ -2,6 +2,6 @@ // RUN: %clang_cc1 -triple=x86_64 -verify -fopenmp-simd -fopenmp-targets=x86_64 -x c++ -fexceptions -fcxx-exceptions %s void bar() { -#pragma omp target device(ancestor : 1) // expected-error {{Device clause with ancestor device-modifier used without specifying 'requires reverse_offload'}} +#pragma omp target device(ancestor : 1) // expected-error {{device clause with ancestor device-modifier used without specifying 'requires reverse_offload'}} ; } diff --git a/clang/test/OpenMP/target_firstprivate_messages.cpp b/clang/test/OpenMP/target_firstprivate_messages.cpp index 9b211297f5315..2eafb367c0c48 100644 --- a/clang/test/OpenMP/target_firstprivate_messages.cpp +++ b/clang/test/OpenMP/target_firstprivate_messages.cpp @@ -56,7 +56,7 @@ class S5 { S5(int v) : a(v) {} S5 &operator=(S5 &s) { #pragma omp target firstprivate(a) firstprivate(this->a) firstprivate(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp index 3bd432b47e637..10f46687d6379 100644 --- a/clang/test/OpenMP/target_map_messages.cpp +++ b/clang/test/OpenMP/target_map_messages.cpp @@ -681,13 +681,13 @@ T tmain(T argc) { #pragma omp target data map(tofrom: argc > 0 ? x : y) // lt50-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} ge50-error 2 {{expected addressable lvalue in 'map' clause}} #pragma omp target data map(argc) #pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}} -#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} warn-warning 2 {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning 2 {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} -#pragma omp target data map(ba) // warn-warning 2 {{Type 'const S2 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} -#pragma omp target data map(ca) // warn-warning 2 {{Type 'const S3 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} warn-warning 2 {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning 2 {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(ba) // warn-warning 2 {{type 'const S2 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(ca) // warn-warning 2 {{type 'const S3 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} #pragma omp target data map(da) #pragma omp target data map(S2::S2s) #pragma omp target data map(S2::S2sc) -#pragma omp target data map(e, g) // warn-warning 2 {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning 2 {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(e, g) // warn-warning 2 {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning 2 {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} #pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} #pragma omp target data map(k) map(k) // lt50-error 2 {{variable already marked as mapped in current construct}} lt50-note 2 {{used here}} #pragma omp target map(k), map(k[:5]) // lt50-error 2 {{pointer cannot be mapped along with a section derived from itself}} lt50-note 2 {{used here}} @@ -815,14 +815,14 @@ int main(int argc, char **argv) { #pragma omp target data map(tofrom: argc > 0 ? argv[1] : argv[2]) // lt50-error {{expected expression containing only member accesses and/or array sections based on named variables}} ge50-error {{expected addressable lvalue in 'map' clause}} #pragma omp target data map(argc) #pragma omp target data map(S1) // expected-error {{'S1' does not refer to a value}} -#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} warn-warning {{Type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning {{Type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} warn-warning {{type 'const S2' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning {{type 'const S3' is not trivially copyable and not guaranteed to be mapped correctly}} #pragma omp target data map(argv[1]) -#pragma omp target data map(ba) // warn-warning {{Type 'const S2 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} -#pragma omp target data map(ca) // warn-warning {{Type 'const S3 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(ba) // warn-warning {{type 'const S2 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(ca) // warn-warning {{type 'const S3 [5]' is not trivially copyable and not guaranteed to be mapped correctly}} #pragma omp target data map(da) #pragma omp target data map(S2::S2s) #pragma omp target data map(S2::S2sc) -#pragma omp target data map(e, g) // warn-warning {{Type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target data map(e, g) // warn-warning {{type 'S4' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} #pragma omp target data map(h) // expected-error {{threadprivate variables are not allowed in 'map' clause}} #pragma omp target data map(k), map(k) // lt50-error {{variable already marked as mapped in current construct}} lt50-note {{used here}} #pragma omp target map(k), map(k[:5]) // lt50-error {{pointer cannot be mapped along with a section derived from itself}} lt50-note {{used here}} @@ -872,7 +872,7 @@ int main(int argc, char **argv) { {} #pragma omp target firstprivate(j) map(j) // expected-error {{firstprivate variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as firstprivate}} {} -#pragma omp target map(m) // warn-warning {{Type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target map(m) // warn-warning {{type 'S6' is not trivially copyable and not guaranteed to be mapped correctly}} {} #pragma omp target { s.a++; } @@ -920,7 +920,7 @@ int main(int argc, char **argv) { { s.a++; } #pragma omp target map(s.s.s.b[:2]) { s.s.s.b[0]++; } -#pragma omp target map(s8[0:1], s9) // warn-warning {{Type 'class S8' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning {{Type 'class S9' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp target map(s8[0:1], s9) // warn-warning {{type 'class S8' is not trivially copyable and not guaranteed to be mapped correctly}} warn-warning {{type 'class S9' is not trivially copyable and not guaranteed to be mapped correctly}} {} int **BB, *offset, *a; diff --git a/clang/test/OpenMP/target_parallel_for_private_messages.cpp b/clang/test/OpenMP/target_parallel_for_private_messages.cpp index 1c31badf51cd5..81b4be4923d7c 100644 --- a/clang/test/OpenMP/target_parallel_for_private_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_private_messages.cpp @@ -56,7 +56,7 @@ class S5 { S5(int v) : a(v) {} S5 &operator=(S5 &s) { #pragma omp target parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/target_parallel_for_simd_private_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_private_messages.cpp index db9d495698b09..c9b5bac0e693f 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_private_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_private_messages.cpp @@ -56,7 +56,7 @@ class S5 { S5(int v) : a(v) {} S5 &operator=(S5 &s) { #pragma omp target parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/target_private_messages.cpp b/clang/test/OpenMP/target_private_messages.cpp index 7ee0c8cffb9c8..8cdd3a11e87a5 100644 --- a/clang/test/OpenMP/target_private_messages.cpp +++ b/clang/test/OpenMP/target_private_messages.cpp @@ -50,7 +50,7 @@ class S5 { S5(int v) : a(v) {} S5 &operator=(S5 &s) { #pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/target_simd_private_messages.cpp b/clang/test/OpenMP/target_simd_private_messages.cpp index 4a55a506d4abe..f6e4e714f8ff1 100644 --- a/clang/test/OpenMP/target_simd_private_messages.cpp +++ b/clang/test/OpenMP/target_simd_private_messages.cpp @@ -56,7 +56,7 @@ class S5 { S5(int v) : a(v) {} S5 &operator=(S5 &s) { #pragma omp target simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} - for (int k = 0; k < s.a; ++k) // expected-warning {{Type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} + for (int k = 0; k < s.a; ++k) // expected-warning {{type 'S5' is not trivially copyable and not guaranteed to be mapped correctly}} ++s.a; return *this; } diff --git a/clang/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp b/clang/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp index fccf5515998dc..195af52b78924 100644 --- a/clang/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp @@ -119,7 +119,7 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target -#pragma omp teams distribute firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} expected-warning {{Type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp teams distribute firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}} expected-warning {{type 'const S3[5]' is not trivially copyable and not guaranteed to be mapped correctly}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute firstprivate(da, z) diff --git a/clang/test/OpenMP/target_update_messages.cpp b/clang/test/OpenMP/target_update_messages.cpp index 2bf0ade9fe919..83191059202ca 100644 --- a/clang/test/OpenMP/target_update_messages.cpp +++ b/clang/test/OpenMP/target_update_messages.cpp @@ -18,14 +18,14 @@ static int y; #pragma omp declare target(y) void yyy() { -#pragma omp target update to(y) // expected-error {{the host cannot update a declare target variable that is not externally visible.}} +#pragma omp target update to(y) // expected-error {{the host cannot update a declare target variable that is not externally visible}} } int __attribute__((visibility("hidden"))) z; #pragma omp declare target(z) void zzz() { -#pragma omp target update from(z) // expected-error {{the host cannot update a declare target variable that is not externally visible.}} +#pragma omp target update from(z) // expected-error {{the host cannot update a declare target variable that is not externally visible}} } void foo() { diff --git a/clang/test/OpenMP/teams_distribute_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_loop_messages.cpp index 167f653e2cd73..e5f146679e5ff 100644 --- a/clang/test/OpenMP/teams_distribute_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_loop_messages.cpp @@ -416,7 +416,7 @@ int test_with_random_access_iterator() { Iter0 begin0, end0; #pragma omp target #pragma omp teams distribute - for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute @@ -425,31 +425,31 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute - for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(0); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(0); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute - for (begin = GoodIter(0); begin < end; ++begin) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = GoodIter(0); begin < end; ++begin) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute @@ -464,7 +464,7 @@ int test_with_random_access_iterator() { ++begin; #pragma omp target #pragma omp teams distribute - for (begin = end; begin < end; ++begin) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = end; begin < end; ++begin) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute @@ -489,7 +489,7 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute - for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute @@ -551,19 +551,19 @@ class TC { #pragma omp teams distribute // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute - for (IT I = begin; I < end; ++I) { // expected-warning 4 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; ++I) { // expected-warning 4 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -599,7 +599,7 @@ int dotest_gt(IT begin, IT end) { #pragma omp target #pragma omp teams distribute - for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -702,7 +702,7 @@ void test_loop_firstprivate_lastprivate() { S s(4); // expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}} #pragma omp target -#pragma omp teams distribute lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{Type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp teams distribute lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 16; ++i) ; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp index cdfc5eaec2288..67e3ce4dc1577 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp @@ -414,7 +414,7 @@ int test_with_random_access_iterator() { Iter0 begin0, end0; #pragma omp target #pragma omp teams distribute parallel for - for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for @@ -423,31 +423,31 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute parallel for - for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(0); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(0); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for - for (begin = GoodIter(0); begin < end; ++begin) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = GoodIter(0); begin < end; ++begin) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute parallel for @@ -462,7 +462,7 @@ int test_with_random_access_iterator() { ++begin; #pragma omp target #pragma omp teams distribute parallel for - for (begin = end; begin < end; ++begin) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = end; begin < end; ++begin) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute parallel for @@ -487,7 +487,7 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute parallel for - for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for @@ -549,19 +549,19 @@ class TC { #pragma omp teams distribute parallel for // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute parallel for // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute parallel for - for (IT I = begin; I < end; ++I) { // expected-warning 4 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; ++I) { // expected-warning 4 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -597,7 +597,7 @@ int dotest_gt(IT begin, IT end) { #pragma omp target #pragma omp teams distribute parallel for - for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -697,7 +697,7 @@ void test_loop_firstprivate_lastprivate() { S s(4); // expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}} #pragma omp target -#pragma omp teams distribute parallel for lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{Type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp teams distribute parallel for lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 16; ++i) ; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp index 645035a3a1632..7ee8b9c9d367f 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp @@ -416,7 +416,7 @@ int test_with_random_access_iterator() { Iter0 begin0, end0; #pragma omp target #pragma omp teams distribute parallel for simd - for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd @@ -425,31 +425,31 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute parallel for simd - for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(0); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(0); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd - for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute parallel for simd @@ -464,7 +464,7 @@ int test_with_random_access_iterator() { ++begin; #pragma omp target #pragma omp teams distribute parallel for simd - for (begin = end; begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = end; begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute parallel for simd @@ -489,7 +489,7 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute parallel for simd - for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute parallel for simd @@ -551,19 +551,19 @@ class TC { #pragma omp teams distribute parallel for simd // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute parallel for simd // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute parallel for simd - for (IT I = begin; I < end; ++I) { // expected-warning 4 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; ++I) { // expected-warning 4 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -599,7 +599,7 @@ int dotest_gt(IT begin, IT end) { #pragma omp target #pragma omp teams distribute parallel for simd - for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -699,7 +699,7 @@ void test_loop_firstprivate_lastprivate() { S s(4); // expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}} #pragma omp target -#pragma omp teams distribute parallel for simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{Type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp teams distribute parallel for simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 16; ++i) ; } diff --git a/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp index 13eef6a98b3db..8bfddbf6e9eec 100644 --- a/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp @@ -416,7 +416,7 @@ int test_with_random_access_iterator() { Iter0 begin0, end0; #pragma omp target #pragma omp teams distribute simd - for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd @@ -425,31 +425,31 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute simd - for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; --I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(begin); I < end; ++I) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(nullptr); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(0); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(0); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd // expected-warning@+1 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}} - for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I(1, 2); I < end; ++I) // expected-warning {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd - for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = GoodIter(0); begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute simd @@ -464,7 +464,7 @@ int test_with_random_access_iterator() { ++begin; #pragma omp target #pragma omp teams distribute simd - for (begin = end; begin < end; ++begin) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (begin = end; begin < end; ++begin) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++begin; #pragma omp target #pragma omp teams distribute simd @@ -489,7 +489,7 @@ int test_with_random_access_iterator() { ++I; #pragma omp target #pragma omp teams distribute simd - for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (GoodIter I = begin; I >= end; I = I - 1) // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; #pragma omp target #pragma omp teams distribute simd @@ -551,19 +551,19 @@ class TC { #pragma omp teams distribute simd // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I = I + ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute simd // expected-note@+2 {{loop step is expected to be positive due to this condition}} // expected-error@+1 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}} - for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I <= end; I += ST) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } #pragma omp target #pragma omp teams distribute simd - for (IT I = begin; I < end; ++I) { // expected-warning 4 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; ++I) { // expected-warning 4 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -599,7 +599,7 @@ int dotest_gt(IT begin, IT end) { #pragma omp target #pragma omp teams distribute simd - for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{Type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} + for (IT I = begin; I < end; I += TC::step()) { // expected-warning 2 {{type 'GoodIter' is not trivially copyable and not guaranteed to be mapped correctly}} ++I; } } @@ -699,7 +699,7 @@ void test_loop_firstprivate_lastprivate() { S s(4); // expected-error@+2 {{lastprivate variable cannot be firstprivate}} expected-note@+2 {{defined as lastprivate}} #pragma omp target -#pragma omp teams distribute simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{Type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} +#pragma omp teams distribute simd lastprivate(s) firstprivate(s) // expected-error {{calling a private constructor of class 'S'}} expected-warning {{type 'S' is not trivially copyable and not guaranteed to be mapped correctly}} for (int i = 0; i < 16; ++i) ; } diff --git a/clang/test/OpenMP/threadprivate_codegen.cpp b/clang/test/OpenMP/threadprivate_codegen.cpp index d0bd2b411ec84..b27783be829d6 100644 --- a/clang/test/OpenMP/threadprivate_codegen.cpp +++ b/clang/test/OpenMP/threadprivate_codegen.cpp @@ -1039,40 +1039,40 @@ int foobar() { // CHECK1-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1 // CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// CHECK1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// CHECK1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // CHECK1: invoke.cont3: // CHECK1-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1 // CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// CHECK1-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]] +// CHECK1-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]] // CHECK1: invoke.cont5: // CHECK1-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1 // CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK1-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0 // CHECK1-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// CHECK1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]] // CHECK1: invoke.cont11: // CHECK1-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1 // CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// CHECK1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]] +// CHECK1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]] // CHECK1: invoke.cont13: // CHECK1-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1 // CHECK1-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// CHECK1-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]] +// CHECK1-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]] // CHECK1: invoke.cont15: // CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK1-NEXT: ret ptr [[TMP2]] // CHECK1: lpad: // CHECK1-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 } -// CHECK1-NEXT: cleanup +// CHECK1-NEXT: cleanup // CHECK1-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0 // CHECK1-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1 @@ -1090,7 +1090,7 @@ int foobar() { // CHECK1-NEXT: br label [[EHCLEANUP:%.*]] // CHECK1: lpad10: // CHECK1-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// CHECK1-NEXT: cleanup +// CHECK1-NEXT: cleanup // CHECK1-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 // CHECK1-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 @@ -1254,34 +1254,34 @@ int foobar() { // CHECK1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] // CHECK1: invoke.cont2: // CHECK1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// CHECK1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// CHECK1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // CHECK1: invoke.cont3: // CHECK1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// CHECK1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] // CHECK1: invoke.cont7: // CHECK1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// CHECK1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] +// CHECK1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] // CHECK1: invoke.cont8: // CHECK1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// CHECK1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] +// CHECK1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] // CHECK1: invoke.cont9: // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]] // CHECK1-NEXT: ret void // CHECK1: lpad: // CHECK1-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// CHECK1-NEXT: cleanup +// CHECK1-NEXT: cleanup // CHECK1-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 // CHECK1-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 @@ -1299,7 +1299,7 @@ int foobar() { // CHECK1-NEXT: br label [[EHCLEANUP:%.*]] // CHECK1: lpad6: // CHECK1-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK1-NEXT: cleanup +// CHECK1-NEXT: cleanup // CHECK1-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 // CHECK1-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 @@ -1375,7 +1375,7 @@ int foobar() { // CHECK1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP4]], i32 0, i32 0 // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4 // CHECK1-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP5]]) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: [[TMP6:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]] // CHECK1-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]] @@ -1436,7 +1436,7 @@ int foobar() { // CHECK1-NEXT: ret i32 [[TMP32]] // CHECK1: lpad: // CHECK1-NEXT: [[TMP33:%.*]] = landingpad { ptr, i32 } -// CHECK1-NEXT: cleanup +// CHECK1-NEXT: cleanup // CHECK1-NEXT: [[TMP34:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 0 // CHECK1-NEXT: store ptr [[TMP34]], ptr [[EXN_SLOT]], align 8 // CHECK1-NEXT: [[TMP35:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 1 @@ -1525,7 +1525,7 @@ int foobar() { // // // CHECK1-LABEL: define {{[^@]+}}@_Z6foobarv -// CHECK1-SAME: () #[[ATTR5:[0-9]+]] { +// CHECK1-SAME: () #[[ATTR2]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RES:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) @@ -1777,34 +1777,34 @@ int foobar() { // CHECK2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] // CHECK2: invoke.cont2: // CHECK2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// CHECK2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// CHECK2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // CHECK2: invoke.cont3: // CHECK2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// CHECK2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] // CHECK2: invoke.cont7: // CHECK2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// CHECK2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] +// CHECK2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] // CHECK2: invoke.cont8: // CHECK2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// CHECK2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] +// CHECK2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] // CHECK2: invoke.cont9: // CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]] // CHECK2-NEXT: ret void // CHECK2: lpad: // CHECK2-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: cleanup +// CHECK2-NEXT: cleanup // CHECK2-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 // CHECK2-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 @@ -1822,7 +1822,7 @@ int foobar() { // CHECK2-NEXT: br label [[EHCLEANUP:%.*]] // CHECK2: lpad6: // CHECK2-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: cleanup +// CHECK2-NEXT: cleanup // CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 // CHECK2-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 @@ -1891,40 +1891,40 @@ int foobar() { // CHECK2-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0 // CHECK2-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1 // CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// CHECK2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// CHECK2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // CHECK2: invoke.cont3: // CHECK2-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1 // CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// CHECK2-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]] +// CHECK2-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]] // CHECK2: invoke.cont5: // CHECK2-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1 // CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK2-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0 // CHECK2-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// CHECK2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]] // CHECK2: invoke.cont11: // CHECK2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1 // CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// CHECK2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]] +// CHECK2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]] // CHECK2: invoke.cont13: // CHECK2-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1 // CHECK2-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8 // CHECK2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// CHECK2-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]] +// CHECK2-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]] // CHECK2: invoke.cont15: // CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8 // CHECK2-NEXT: ret ptr [[TMP2]] // CHECK2: lpad: // CHECK2-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: cleanup +// CHECK2-NEXT: cleanup // CHECK2-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0 // CHECK2-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1 @@ -1942,7 +1942,7 @@ int foobar() { // CHECK2-NEXT: br label [[EHCLEANUP:%.*]] // CHECK2: lpad10: // CHECK2-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: cleanup +// CHECK2-NEXT: cleanup // CHECK2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0 // CHECK2-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1 @@ -2029,7 +2029,7 @@ int foobar() { // CHECK2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP4]], i32 0, i32 0 // CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4 // CHECK2-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP5]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: [[TMP6:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]] // CHECK2-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]] @@ -2090,7 +2090,7 @@ int foobar() { // CHECK2-NEXT: ret i32 [[TMP32]] // CHECK2: lpad: // CHECK2-NEXT: [[TMP33:%.*]] = landingpad { ptr, i32 } -// CHECK2-NEXT: cleanup +// CHECK2-NEXT: cleanup // CHECK2-NEXT: [[TMP34:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 0 // CHECK2-NEXT: store ptr [[TMP34]], ptr [[EXN_SLOT]], align 8 // CHECK2-NEXT: [[TMP35:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 1 @@ -2154,7 +2154,7 @@ int foobar() { // // // CHECK2-LABEL: define {{[^@]+}}@_Z6foobarv -// CHECK2-SAME: () #[[ATTR5:[0-9]+]] { +// CHECK2-SAME: () #[[ATTR2]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[RES:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) @@ -2452,34 +2452,34 @@ int foobar() { // SIMD1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8 // SIMD1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // SIMD1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// SIMD1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// SIMD1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // SIMD1: invoke.cont: // SIMD1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // SIMD1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// SIMD1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// SIMD1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] // SIMD1: invoke.cont2: // SIMD1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // SIMD1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// SIMD1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// SIMD1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // SIMD1: invoke.cont3: // SIMD1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8 // SIMD1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // SIMD1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// SIMD1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] +// SIMD1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] // SIMD1: invoke.cont7: // SIMD1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // SIMD1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// SIMD1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] +// SIMD1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] // SIMD1: invoke.cont8: // SIMD1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // SIMD1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// SIMD1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] +// SIMD1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] // SIMD1: invoke.cont9: // SIMD1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]] // SIMD1-NEXT: ret void // SIMD1: lpad: // SIMD1-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// SIMD1-NEXT: cleanup +// SIMD1-NEXT: cleanup // SIMD1-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 // SIMD1-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 // SIMD1-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 @@ -2497,7 +2497,7 @@ int foobar() { // SIMD1-NEXT: br label [[EHCLEANUP:%.*]] // SIMD1: lpad6: // SIMD1-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// SIMD1-NEXT: cleanup +// SIMD1-NEXT: cleanup // SIMD1-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 // SIMD1-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8 // SIMD1-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 @@ -2568,7 +2568,7 @@ int foobar() { // SIMD1: init: // SIMD1-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZL3gs1, align 4 // SIMD1-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP2]]) -// SIMD1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// SIMD1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // SIMD1: invoke.cont: // SIMD1-NEXT: [[TMP3:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]] // SIMD1-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]] @@ -2613,7 +2613,7 @@ int foobar() { // SIMD1-NEXT: ret i32 [[TMP21]] // SIMD1: lpad: // SIMD1-NEXT: [[TMP22:%.*]] = landingpad { ptr, i32 } -// SIMD1-NEXT: cleanup +// SIMD1-NEXT: cleanup // SIMD1-NEXT: [[TMP23:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 0 // SIMD1-NEXT: store ptr [[TMP23]], ptr [[EXN_SLOT]], align 8 // SIMD1-NEXT: [[TMP24:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 1 @@ -2652,7 +2652,7 @@ int foobar() { // // // SIMD1-LABEL: define {{[^@]+}}@_Z6foobarv -// SIMD1-SAME: () #[[ATTR5:[0-9]+]] { +// SIMD1-SAME: () #[[ATTR2]] { // SIMD1-NEXT: entry: // SIMD1-NEXT: [[RES:%.*]] = alloca i32, align 4 // SIMD1-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN6Static1sE, align 4 @@ -2840,179 +2840,179 @@ int foobar() { // SIMD2-LABEL: define {{[^@]+}}@__cxx_global_var_init // SIMD2-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG115:![0-9]+]] { // SIMD2-NEXT: entry: -// SIMD2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG119:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR3:[0-9]+]], !dbg [[DBG121:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG122:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG118:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR3:[0-9]+]], !dbg [[DBG120:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG121:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S1C1Ei -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 !dbg [[DBG123:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 !dbg [[DBG122:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META124:![0-9]+]], metadata !DIExpression()), !dbg [[DBG126:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META123:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META126:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG129:![0-9]+]] -// SIMD2-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG129]] -// SIMD2-NEXT: ret void, !dbg [[DBG130:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG128:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG128]] +// SIMD2-NEXT: ret void, !dbg [[DBG129:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S1D1Ev -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG131:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG130:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG132:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]], !dbg [[DBG134:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG135:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]], !dbg [[DBG133:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG134:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 -// SIMD2-SAME: () #[[ATTR0]] !dbg [[DBG136:![0-9]+]] { +// SIMD2-SAME: () #[[ATTR0]] !dbg [[DBG135:![0-9]+]] { // SIMD2-NEXT: entry: -// SIMD2-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG137:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG139:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG140:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG136:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG138:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG139:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S2C1Ei -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG141:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG140:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META142:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META141:![0-9]+]], metadata !DIExpression()), !dbg [[DBG143:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META145:![0-9]+]], metadata !DIExpression()), !dbg [[DBG146:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META144:![0-9]+]], metadata !DIExpression()), !dbg [[DBG145:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG147:![0-9]+]] -// SIMD2-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG147]] -// SIMD2-NEXT: ret void, !dbg [[DBG148:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG146:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG146]] +// SIMD2-NEXT: ret void, !dbg [[DBG147:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S2D1Ev -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG149:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG148:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG151:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META149:![0-9]+]], metadata !DIExpression()), !dbg [[DBG150:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR3]], !dbg [[DBG152:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG153:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR3]], !dbg [[DBG151:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG152:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@__cxx_global_var_init.2 -// SIMD2-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG154:![0-9]+]] { +// SIMD2-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG153:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // SIMD2-NEXT: [[ARRAYINIT_ENDOFINIT5:%.*]] = alloca ptr, align 8 -// SIMD2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG155:![0-9]+]] -// SIMD2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157:![0-9]+]] +// SIMD2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG154:![0-9]+]] +// SIMD2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156:![0-9]+]] // SIMD2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// SIMD2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG158:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG157:![0-9]+]] // SIMD2: invoke.cont: -// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157]] +// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156]] // SIMD2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// SIMD2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG159:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG158:![0-9]+]] // SIMD2: invoke.cont2: -// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157]] +// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156]] // SIMD2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// SIMD2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG160:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG159:![0-9]+]] // SIMD2: invoke.cont3: -// SIMD2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG155]] -// SIMD2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161:![0-9]+]] +// SIMD2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG154]] +// SIMD2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160:![0-9]+]] // SIMD2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// SIMD2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG162:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG161:![0-9]+]] // SIMD2: invoke.cont7: -// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161]] +// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160]] // SIMD2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// SIMD2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG163:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG162:![0-9]+]] // SIMD2: invoke.cont8: -// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161]] +// SIMD2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160]] // SIMD2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// SIMD2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG164:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG163:![0-9]+]] // SIMD2: invoke.cont9: -// SIMD2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG165:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG165]] +// SIMD2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG164:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG164]] // SIMD2: lpad: // SIMD2-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// SIMD2-NEXT: cleanup, !dbg [[DBG166:![0-9]+]] -// SIMD2-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG166]] -// SIMD2-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG166]] -// SIMD2-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG166]] -// SIMD2-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG166]] -// SIMD2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157]] -// SIMD2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG157]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG157]] +// SIMD2-NEXT: cleanup, !dbg [[DBG165:![0-9]+]] +// SIMD2-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG165]] +// SIMD2-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG165]] +// SIMD2-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG165]] +// SIMD2-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG165]] +// SIMD2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156]] +// SIMD2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG156]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG156]] // SIMD2: arraydestroy.body: -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG157]] -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG157]] -// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG157]] -// SIMD2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG157]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG157]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG156]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG156]] +// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG156]] +// SIMD2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG156]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG156]] // SIMD2: arraydestroy.done4: -// SIMD2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG157]] +// SIMD2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG156]] // SIMD2: lpad6: // SIMD2-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// SIMD2-NEXT: cleanup, !dbg [[DBG166]] -// SIMD2-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG166]] -// SIMD2-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG166]] -// SIMD2-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG166]] -// SIMD2-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG166]] -// SIMD2-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161]] -// SIMD2-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG161]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG161]] +// SIMD2-NEXT: cleanup, !dbg [[DBG165]] +// SIMD2-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG165]] +// SIMD2-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG165]] +// SIMD2-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG165]] +// SIMD2-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG165]] +// SIMD2-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160]] +// SIMD2-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG160]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG160]] // SIMD2: arraydestroy.body11: -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG161]] -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG161]] -// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR3]], !dbg [[DBG161]] -// SIMD2-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG161]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG161]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG160]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG160]] +// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR3]], !dbg [[DBG160]] +// SIMD2-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG160]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG160]] // SIMD2: arraydestroy.done15: -// SIMD2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG161]] +// SIMD2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG160]] // SIMD2: ehcleanup: -// SIMD2-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG155]] -// SIMD2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG155]] -// SIMD2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG155]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG155]] +// SIMD2-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG154]] +// SIMD2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG154]] +// SIMD2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG154]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG154]] // SIMD2: arraydestroy.body17: -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG155]] -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG155]] -// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]], !dbg [[DBG155]] -// SIMD2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG155]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG155]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG154]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG154]] +// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]], !dbg [[DBG154]] +// SIMD2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG154]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG154]] // SIMD2: arraydestroy.done21: -// SIMD2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG155]] +// SIMD2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG154]] // SIMD2: eh.resume: -// SIMD2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG155]] -// SIMD2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG155]] -// SIMD2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG155]] -// SIMD2-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG155]] -// SIMD2-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG155]] +// SIMD2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG154]] +// SIMD2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG154]] +// SIMD2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG154]] +// SIMD2-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG154]] +// SIMD2-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG154]] // // // SIMD2-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// SIMD2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG167:![0-9]+]] { +// SIMD2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG166:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG172:![0-9]+]] -// SIMD2-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG172]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META170:![0-9]+]], metadata !DIExpression()), !dbg [[DBG171:![0-9]+]] +// SIMD2-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG171]] // SIMD2: arraydestroy.body: -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG172]] -// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG172]] -// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG172]] -// SIMD2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG172]] -// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG172]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG171]] +// SIMD2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG171]] +// SIMD2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG171]] +// SIMD2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG171]] +// SIMD2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG171]] // SIMD2: arraydestroy.done1: -// SIMD2-NEXT: ret void, !dbg [[DBG172]] +// SIMD2-NEXT: ret void, !dbg [[DBG171]] // // // SIMD2-LABEL: define {{[^@]+}}@main @@ -3023,302 +3023,302 @@ int foobar() { // SIMD2-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META173:![0-9]+]], metadata !DIExpression()), !dbg [[DBG174:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = load atomic i8, ptr @_ZGVZ4mainE2sm acquire, align 8, !dbg [[DBG175:![0-9]+]] -// SIMD2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG175]] -// SIMD2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG175]], !prof [[PROF176:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG173:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load atomic i8, ptr @_ZGVZ4mainE2sm acquire, align 8, !dbg [[DBG174:![0-9]+]] +// SIMD2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG174]] +// SIMD2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG174]], !prof [[PROF175:![0-9]+]] // SIMD2: init.check: -// SIMD2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG175]] -// SIMD2-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0, !dbg [[DBG175]] -// SIMD2-NEXT: br i1 [[TOBOOL]], label [[INIT:%.*]], label [[INIT_END]], !dbg [[DBG175]] +// SIMD2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG174]] +// SIMD2-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0, !dbg [[DBG174]] +// SIMD2-NEXT: br i1 [[TOBOOL]], label [[INIT:%.*]], label [[INIT_END]], !dbg [[DBG174]] // SIMD2: init: -// SIMD2-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG177:![0-9]+]] +// SIMD2-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG176:![0-9]+]] // SIMD2-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP2]]) -// SIMD2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG178:![0-9]+]] +// SIMD2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG177:![0-9]+]] // SIMD2: invoke.cont: -// SIMD2-NEXT: [[TMP3:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG175]] -// SIMD2-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG175]] -// SIMD2-NEXT: br label [[INIT_END]], !dbg [[DBG175]] +// SIMD2-NEXT: [[TMP3:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG174]] +// SIMD2-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG174]] +// SIMD2-NEXT: br label [[INIT_END]], !dbg [[DBG174]] // SIMD2: init.end: -// SIMD2-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG179:![0-9]+]] -// SIMD2-NEXT: store i32 [[TMP4]], ptr [[RES]], align 4, !dbg [[DBG180:![0-9]+]] -// SIMD2-NEXT: [[TMP5:%.*]] = load i32, ptr @_ZZ4mainE2sm, align 8, !dbg [[DBG181:![0-9]+]] -// SIMD2-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG182:![0-9]+]] -// SIMD2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG182]] -// SIMD2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG182]] -// SIMD2-NEXT: [[TMP7:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG183:![0-9]+]] -// SIMD2-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG184:![0-9]+]] -// SIMD2-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG184]] -// SIMD2-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG184]] -// SIMD2-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG185:![0-9]+]] -// SIMD2-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG186:![0-9]+]] -// SIMD2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG186]] -// SIMD2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG186]] -// SIMD2-NEXT: [[TMP11:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG187:![0-9]+]] -// SIMD2-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG188:![0-9]+]] -// SIMD2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG188]] -// SIMD2-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG188]] -// SIMD2-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG189:![0-9]+]] -// SIMD2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG190:![0-9]+]] -// SIMD2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG190]] -// SIMD2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG190]] -// SIMD2-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG191:![0-9]+]] -// SIMD2-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG192:![0-9]+]] -// SIMD2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG192]] -// SIMD2-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG192]] -// SIMD2-NEXT: [[TMP17:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG193:![0-9]+]] -// SIMD2-NEXT: [[CONV:%.*]] = fptosi float [[TMP17]] to i32, !dbg [[DBG193]] -// SIMD2-NEXT: [[TMP18:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG194:![0-9]+]] -// SIMD2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP18]], [[CONV]], !dbg [[DBG194]] -// SIMD2-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG194]] -// SIMD2-NEXT: [[TMP19:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG195:![0-9]+]] -// SIMD2-NEXT: [[TMP20:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG196:![0-9]+]] -// SIMD2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP20]], [[TMP19]], !dbg [[DBG196]] -// SIMD2-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG196]] -// SIMD2-NEXT: [[TMP21:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG197:![0-9]+]] -// SIMD2-NEXT: ret i32 [[TMP21]], !dbg [[DBG198:![0-9]+]] +// SIMD2-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG178:![0-9]+]] +// SIMD2-NEXT: store i32 [[TMP4]], ptr [[RES]], align 4, !dbg [[DBG179:![0-9]+]] +// SIMD2-NEXT: [[TMP5:%.*]] = load i32, ptr @_ZZ4mainE2sm, align 8, !dbg [[DBG180:![0-9]+]] +// SIMD2-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG181:![0-9]+]] +// SIMD2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG181]] +// SIMD2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG181]] +// SIMD2-NEXT: [[TMP7:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG182:![0-9]+]] +// SIMD2-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG183:![0-9]+]] +// SIMD2-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG183]] +// SIMD2-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG183]] +// SIMD2-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG184:![0-9]+]] +// SIMD2-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG185:![0-9]+]] +// SIMD2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG185]] +// SIMD2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG185]] +// SIMD2-NEXT: [[TMP11:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG186:![0-9]+]] +// SIMD2-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG187:![0-9]+]] +// SIMD2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG187]] +// SIMD2-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG187]] +// SIMD2-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG188:![0-9]+]] +// SIMD2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG189:![0-9]+]] +// SIMD2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG189]] +// SIMD2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG189]] +// SIMD2-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG190:![0-9]+]] +// SIMD2-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG191:![0-9]+]] +// SIMD2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG191]] +// SIMD2-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG191]] +// SIMD2-NEXT: [[TMP17:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG192:![0-9]+]] +// SIMD2-NEXT: [[CONV:%.*]] = fptosi float [[TMP17]] to i32, !dbg [[DBG192]] +// SIMD2-NEXT: [[TMP18:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG193:![0-9]+]] +// SIMD2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP18]], [[CONV]], !dbg [[DBG193]] +// SIMD2-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG193]] +// SIMD2-NEXT: [[TMP19:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG194:![0-9]+]] +// SIMD2-NEXT: [[TMP20:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG195:![0-9]+]] +// SIMD2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP20]], [[TMP19]], !dbg [[DBG195]] +// SIMD2-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG195]] +// SIMD2-NEXT: [[TMP21:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG196:![0-9]+]] +// SIMD2-NEXT: ret i32 [[TMP21]], !dbg [[DBG197:![0-9]+]] // SIMD2: lpad: // SIMD2-NEXT: [[TMP22:%.*]] = landingpad { ptr, i32 } -// SIMD2-NEXT: cleanup, !dbg [[DBG199:![0-9]+]] -// SIMD2-NEXT: [[TMP23:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 0, !dbg [[DBG199]] -// SIMD2-NEXT: store ptr [[TMP23]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG199]] -// SIMD2-NEXT: [[TMP24:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 1, !dbg [[DBG199]] -// SIMD2-NEXT: store i32 [[TMP24]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG199]] -// SIMD2-NEXT: call void @__cxa_guard_abort(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG175]] -// SIMD2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG175]] +// SIMD2-NEXT: cleanup, !dbg [[DBG198:![0-9]+]] +// SIMD2-NEXT: [[TMP23:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 0, !dbg [[DBG198]] +// SIMD2-NEXT: store ptr [[TMP23]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG198]] +// SIMD2-NEXT: [[TMP24:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 1, !dbg [[DBG198]] +// SIMD2-NEXT: store i32 [[TMP24]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG198]] +// SIMD2-NEXT: call void @__cxa_guard_abort(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG174]] +// SIMD2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG174]] // SIMD2: eh.resume: -// SIMD2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG175]] -// SIMD2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG175]] -// SIMD2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG175]] -// SIMD2-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG175]] -// SIMD2-NEXT: resume { ptr, i32 } [[LPAD_VAL8]], !dbg [[DBG175]] +// SIMD2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG174]] +// SIMD2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG174]] +// SIMD2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG174]] +// SIMD2-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG174]] +// SIMD2-NEXT: resume { ptr, i32 } [[LPAD_VAL8]], !dbg [[DBG174]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC1Ei -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG200:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG199:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META201:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META200:![0-9]+]], metadata !DIExpression()), !dbg [[DBG202:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG205:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META203:![0-9]+]], metadata !DIExpression()), !dbg [[DBG204:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG206:![0-9]+]] -// SIMD2-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG206]] -// SIMD2-NEXT: ret void, !dbg [[DBG207:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG205:![0-9]+]] +// SIMD2-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG205]] +// SIMD2-NEXT: ret void, !dbg [[DBG206:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD1Ev -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG208:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG207:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META209:![0-9]+]], metadata !DIExpression()), !dbg [[DBG210:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META208:![0-9]+]], metadata !DIExpression()), !dbg [[DBG209:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR3]], !dbg [[DBG211:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG212:![0-9]+]] +// SIMD2-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR3]], !dbg [[DBG210:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG211:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_Z6foobarv -// SIMD2-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG213:![0-9]+]] { +// SIMD2-SAME: () #[[ATTR2]] !dbg [[DBG212:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[RES:%.*]] = alloca i32, align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META214:![0-9]+]], metadata !DIExpression()), !dbg [[DBG215:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG216:![0-9]+]] -// SIMD2-NEXT: store i32 [[TMP0]], ptr [[RES]], align 4, !dbg [[DBG217:![0-9]+]] -// SIMD2-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG218:![0-9]+]] -// SIMD2-NEXT: [[TMP2:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG219:![0-9]+]] -// SIMD2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]], !dbg [[DBG219]] -// SIMD2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG219]] -// SIMD2-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG220:![0-9]+]] -// SIMD2-NEXT: [[TMP4:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG221:![0-9]+]] -// SIMD2-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], [[TMP3]], !dbg [[DBG221]] -// SIMD2-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG221]] -// SIMD2-NEXT: [[TMP5:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG222:![0-9]+]] -// SIMD2-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG223:![0-9]+]] -// SIMD2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG223]] -// SIMD2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG223]] -// SIMD2-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG224:![0-9]+]] -// SIMD2-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG225:![0-9]+]] -// SIMD2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG225]] -// SIMD2-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG225]] -// SIMD2-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG226:![0-9]+]] -// SIMD2-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG227:![0-9]+]] -// SIMD2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG227]] -// SIMD2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG227]] -// SIMD2-NEXT: [[TMP11:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG228:![0-9]+]] -// SIMD2-NEXT: [[CONV:%.*]] = fptosi float [[TMP11]] to i32, !dbg [[DBG228]] -// SIMD2-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG229:![0-9]+]] -// SIMD2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP12]], [[CONV]], !dbg [[DBG229]] -// SIMD2-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG229]] -// SIMD2-NEXT: [[TMP13:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG230:![0-9]+]] -// SIMD2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] -// SIMD2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG231]] -// SIMD2-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG231]] -// SIMD2-NEXT: [[TMP15:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG232:![0-9]+]] -// SIMD2-NEXT: ret i32 [[TMP15]], !dbg [[DBG233:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META213:![0-9]+]], metadata !DIExpression()), !dbg [[DBG214:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG215:![0-9]+]] +// SIMD2-NEXT: store i32 [[TMP0]], ptr [[RES]], align 4, !dbg [[DBG216:![0-9]+]] +// SIMD2-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG217:![0-9]+]] +// SIMD2-NEXT: [[TMP2:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG218:![0-9]+]] +// SIMD2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]], !dbg [[DBG218]] +// SIMD2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG218]] +// SIMD2-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG219:![0-9]+]] +// SIMD2-NEXT: [[TMP4:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG220:![0-9]+]] +// SIMD2-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], [[TMP3]], !dbg [[DBG220]] +// SIMD2-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG220]] +// SIMD2-NEXT: [[TMP5:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG221:![0-9]+]] +// SIMD2-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG222:![0-9]+]] +// SIMD2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG222]] +// SIMD2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG222]] +// SIMD2-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG223:![0-9]+]] +// SIMD2-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG224:![0-9]+]] +// SIMD2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG224]] +// SIMD2-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG224]] +// SIMD2-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG225:![0-9]+]] +// SIMD2-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG226:![0-9]+]] +// SIMD2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG226]] +// SIMD2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG226]] +// SIMD2-NEXT: [[TMP11:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG227:![0-9]+]] +// SIMD2-NEXT: [[CONV:%.*]] = fptosi float [[TMP11]] to i32, !dbg [[DBG227]] +// SIMD2-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG228:![0-9]+]] +// SIMD2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP12]], [[CONV]], !dbg [[DBG228]] +// SIMD2-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG228]] +// SIMD2-NEXT: [[TMP13:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG229:![0-9]+]] +// SIMD2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG230:![0-9]+]] +// SIMD2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG230]] +// SIMD2-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG230]] +// SIMD2-NEXT: [[TMP15:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] +// SIMD2-NEXT: ret i32 [[TMP15]], !dbg [[DBG232:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@__cxx_global_var_init.3 -// SIMD2-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG234:![0-9]+]] { +// SIMD2-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG233:![0-9]+]] { // SIMD2-NEXT: entry: -// SIMD2-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG235:![0-9]+]] -// SIMD2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG235]] -// SIMD2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG235]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234:![0-9]+]] +// SIMD2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG234]] +// SIMD2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG234]] // SIMD2: init.check: -// SIMD2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG235]] -// SIMD2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG236:![0-9]+]] -// SIMD2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG235]] -// SIMD2-NEXT: br label [[INIT_END]], !dbg [[DBG235]] +// SIMD2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234]] +// SIMD2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG235:![0-9]+]] +// SIMD2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG234]] +// SIMD2-NEXT: br label [[INIT_END]], !dbg [[DBG234]] // SIMD2: init.end: -// SIMD2-NEXT: ret void, !dbg [[DBG238:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG237:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S4C1Ei -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG239:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG238:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META240:![0-9]+]], metadata !DIExpression()), !dbg [[DBG242:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META239:![0-9]+]], metadata !DIExpression()), !dbg [[DBG241:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META243:![0-9]+]], metadata !DIExpression()), !dbg [[DBG244:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META242:![0-9]+]], metadata !DIExpression()), !dbg [[DBG243:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG245:![0-9]+]] -// SIMD2-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG245]] -// SIMD2-NEXT: ret void, !dbg [[DBG246:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG244:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG244]] +// SIMD2-NEXT: ret void, !dbg [[DBG245:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S4D1Ev -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG247:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG246:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META248:![0-9]+]], metadata !DIExpression()), !dbg [[DBG249:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META247:![0-9]+]], metadata !DIExpression()), !dbg [[DBG248:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]], !dbg [[DBG250:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG251:![0-9]+]] +// SIMD2-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]], !dbg [[DBG249:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG250:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S1C2Ei -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG252:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG251:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META253:![0-9]+]], metadata !DIExpression()), !dbg [[DBG254:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META252:![0-9]+]], metadata !DIExpression()), !dbg [[DBG253:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META255:![0-9]+]], metadata !DIExpression()), !dbg [[DBG256:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META254:![0-9]+]], metadata !DIExpression()), !dbg [[DBG255:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG257:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG258:![0-9]+]] -// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG257]] -// SIMD2-NEXT: ret void, !dbg [[DBG259:![0-9]+]] +// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG256:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG257:![0-9]+]] +// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG256]] +// SIMD2-NEXT: ret void, !dbg [[DBG258:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S1D2Ev -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG260:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG259:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META261:![0-9]+]], metadata !DIExpression()), !dbg [[DBG262:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META260:![0-9]+]], metadata !DIExpression()), !dbg [[DBG261:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG263:![0-9]+]] -// SIMD2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG265:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG266:![0-9]+]] +// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG262:![0-9]+]] +// SIMD2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG264:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG265:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S2C2Ei -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG267:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG266:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META268:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META267:![0-9]+]], metadata !DIExpression()), !dbg [[DBG268:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META270:![0-9]+]], metadata !DIExpression()), !dbg [[DBG271:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META269:![0-9]+]], metadata !DIExpression()), !dbg [[DBG270:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG272:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG273:![0-9]+]] -// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG272]] -// SIMD2-NEXT: ret void, !dbg [[DBG274:![0-9]+]] +// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG271:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG272:![0-9]+]] +// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG271]] +// SIMD2-NEXT: ret void, !dbg [[DBG273:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S2D2Ev -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG275:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG274:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META276:![0-9]+]], metadata !DIExpression()), !dbg [[DBG277:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META275:![0-9]+]], metadata !DIExpression()), !dbg [[DBG276:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG278:![0-9]+]] -// SIMD2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG280:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG281:![0-9]+]] +// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG277:![0-9]+]] +// SIMD2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG279:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG280:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC2Ei -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG282:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG281:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META283:![0-9]+]], metadata !DIExpression()), !dbg [[DBG284:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META282:![0-9]+]], metadata !DIExpression()), !dbg [[DBG283:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META285:![0-9]+]], metadata !DIExpression()), !dbg [[DBG286:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META284:![0-9]+]], metadata !DIExpression()), !dbg [[DBG285:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG287:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG288:![0-9]+]] -// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG287]] -// SIMD2-NEXT: ret void, !dbg [[DBG289:![0-9]+]] +// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG286:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG287:![0-9]+]] +// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG286]] +// SIMD2-NEXT: ret void, !dbg [[DBG288:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD2Ev -// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG290:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG289:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META291:![0-9]+]], metadata !DIExpression()), !dbg [[DBG292:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META290:![0-9]+]], metadata !DIExpression()), !dbg [[DBG291:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG293:![0-9]+]] -// SIMD2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG295:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG296:![0-9]+]] +// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG292:![0-9]+]] +// SIMD2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG294:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG295:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S4C2Ei -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG297:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG296:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META298:![0-9]+]], metadata !DIExpression()), !dbg [[DBG299:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META297:![0-9]+]], metadata !DIExpression()), !dbg [[DBG298:![0-9]+]] // SIMD2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META300:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META299:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG302:![0-9]+]] -// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG303:![0-9]+]] -// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG302]] -// SIMD2-NEXT: ret void, !dbg [[DBG304:![0-9]+]] +// SIMD2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG301:![0-9]+]] +// SIMD2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG302:![0-9]+]] +// SIMD2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG301]] +// SIMD2-NEXT: ret void, !dbg [[DBG303:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_ZN2S4D2Ev -// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG305:![0-9]+]] { +// SIMD2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG304:![0-9]+]] { // SIMD2-NEXT: entry: // SIMD2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META306:![0-9]+]], metadata !DIExpression()), !dbg [[DBG307:![0-9]+]] +// SIMD2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META305:![0-9]+]], metadata !DIExpression()), !dbg [[DBG306:![0-9]+]] // SIMD2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG308:![0-9]+]] -// SIMD2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG310:![0-9]+]] -// SIMD2-NEXT: ret void, !dbg [[DBG311:![0-9]+]] +// SIMD2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG307:![0-9]+]] +// SIMD2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG309:![0-9]+]] +// SIMD2-NEXT: ret void, !dbg [[DBG310:![0-9]+]] // // // SIMD2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// SIMD2-SAME: () #[[ATTR0]] !dbg [[DBG312:![0-9]+]] { +// SIMD2-SAME: () #[[ATTR0]] !dbg [[DBG311:![0-9]+]] { // SIMD2-NEXT: entry: -// SIMD2-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG314:![0-9]+]] -// SIMD2-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG314]] -// SIMD2-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG314]] +// SIMD2-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG313:![0-9]+]] +// SIMD2-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG313]] +// SIMD2-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG313]] // SIMD2-NEXT: ret void // // @@ -3445,34 +3445,34 @@ int foobar() { // CHECK-TLS1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK-TLS1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK-TLS1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// CHECK-TLS1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK-TLS1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK-TLS1: invoke.cont: // CHECK-TLS1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK-TLS1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// CHECK-TLS1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// CHECK-TLS1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] // CHECK-TLS1: invoke.cont2: // CHECK-TLS1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK-TLS1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// CHECK-TLS1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// CHECK-TLS1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // CHECK-TLS1: invoke.cont3: // CHECK-TLS1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK-TLS1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK-TLS1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// CHECK-TLS1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] +// CHECK-TLS1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] // CHECK-TLS1: invoke.cont7: // CHECK-TLS1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK-TLS1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// CHECK-TLS1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] +// CHECK-TLS1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] // CHECK-TLS1: invoke.cont8: // CHECK-TLS1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK-TLS1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// CHECK-TLS1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] +// CHECK-TLS1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] // CHECK-TLS1: invoke.cont9: // CHECK-TLS1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]] // CHECK-TLS1-NEXT: ret void // CHECK-TLS1: lpad: // CHECK-TLS1-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS1-NEXT: cleanup +// CHECK-TLS1-NEXT: cleanup // CHECK-TLS1-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 // CHECK-TLS1-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 // CHECK-TLS1-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 @@ -3490,7 +3490,7 @@ int foobar() { // CHECK-TLS1-NEXT: br label [[EHCLEANUP:%.*]] // CHECK-TLS1: lpad6: // CHECK-TLS1-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS1-NEXT: cleanup +// CHECK-TLS1-NEXT: cleanup // CHECK-TLS1-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 // CHECK-TLS1-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8 // CHECK-TLS1-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 @@ -3708,7 +3708,7 @@ int foobar() { // // // CHECK-TLS1-LABEL: define {{[^@]+}}@_Z6foobarv -// CHECK-TLS1-SAME: () #[[ATTR7:[0-9]+]] { +// CHECK-TLS1-SAME: () #[[ATTR1]] { // CHECK-TLS1-NEXT: entry: // CHECK-TLS1-NEXT: [[RES:%.*]] = alloca i32, align 4 // CHECK-TLS1-NEXT: [[TMP0:%.*]] = call ptr @_ZTWN6Static1sE() @@ -3997,7 +3997,7 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@_Z6foobarv -// CHECK-TLS2-SAME: () #[[ATTR6:[0-9]+]] { +// CHECK-TLS2-SAME: () #[[ATTR2]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: [[RES:%.*]] = alloca i32, align 4 // CHECK-TLS2-NEXT: [[TMP0:%.*]] = call ptr @_ZTWN6Static1sE() @@ -4050,7 +4050,7 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@__cxx_global_var_init -// CHECK-TLS2-SAME: () #[[ATTR7:[0-9]+]] { +// CHECK-TLS2-SAME: () #[[ATTR6:[0-9]+]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5) // CHECK-TLS2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR4]] @@ -4106,7 +4106,7 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 -// CHECK-TLS2-SAME: () #[[ATTR7]] { +// CHECK-TLS2-SAME: () #[[ATTR6]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27) // CHECK-TLS2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR4]] @@ -4162,7 +4162,7 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@__cxx_global_var_init.2 -// CHECK-TLS2-SAME: () #[[ATTR7]] personality ptr @__gxx_personality_v0 { +// CHECK-TLS2-SAME: () #[[ATTR6]] personality ptr @__gxx_personality_v0 { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // CHECK-TLS2-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 @@ -4172,34 +4172,34 @@ int foobar() { // CHECK-TLS2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK-TLS2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK-TLS2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// CHECK-TLS2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// CHECK-TLS2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK-TLS2: invoke.cont: // CHECK-TLS2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK-TLS2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// CHECK-TLS2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// CHECK-TLS2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] // CHECK-TLS2: invoke.cont2: // CHECK-TLS2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // CHECK-TLS2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// CHECK-TLS2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// CHECK-TLS2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // CHECK-TLS2: invoke.cont3: // CHECK-TLS2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8 // CHECK-TLS2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK-TLS2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// CHECK-TLS2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] +// CHECK-TLS2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] // CHECK-TLS2: invoke.cont7: // CHECK-TLS2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK-TLS2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// CHECK-TLS2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] +// CHECK-TLS2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] // CHECK-TLS2: invoke.cont8: // CHECK-TLS2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // CHECK-TLS2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// CHECK-TLS2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] +// CHECK-TLS2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] // CHECK-TLS2: invoke.cont9: // CHECK-TLS2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR4]] // CHECK-TLS2-NEXT: ret void // CHECK-TLS2: lpad: // CHECK-TLS2-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS2-NEXT: cleanup +// CHECK-TLS2-NEXT: cleanup // CHECK-TLS2-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 // CHECK-TLS2-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 // CHECK-TLS2-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 @@ -4217,7 +4217,7 @@ int foobar() { // CHECK-TLS2-NEXT: br label [[EHCLEANUP:%.*]] // CHECK-TLS2: lpad6: // CHECK-TLS2-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS2-NEXT: cleanup +// CHECK-TLS2-NEXT: cleanup // CHECK-TLS2-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 // CHECK-TLS2-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8 // CHECK-TLS2-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 @@ -4255,7 +4255,7 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// CHECK-TLS2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR7]] { +// CHECK-TLS2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR6]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 @@ -4296,7 +4296,7 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@__cxx_global_var_init.3 -// CHECK-TLS2-SAME: () #[[ATTR7]] { +// CHECK-TLS2-SAME: () #[[ATTR6]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK-TLS2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 @@ -4359,14 +4359,14 @@ int foobar() { // // // CHECK-TLS2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// CHECK-TLS2-SAME: () #[[ATTR7]] { +// CHECK-TLS2-SAME: () #[[ATTR6]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: call void @__cxx_global_var_init.1() // CHECK-TLS2-NEXT: ret void // // // CHECK-TLS2-LABEL: define {{[^@]+}}@__tls_init -// CHECK-TLS2-SAME: () #[[ATTR7]] { +// CHECK-TLS2-SAME: () #[[ATTR6]] { // CHECK-TLS2-NEXT: entry: // CHECK-TLS2-NEXT: [[TMP0:%.*]] = load i8, ptr @__tls_guard, align 1 // CHECK-TLS2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 @@ -4383,235 +4383,235 @@ int foobar() { // CHECK-TLS3-LABEL: define {{[^@]+}}@__cxx_global_var_init // CHECK-TLS3-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG116:![0-9]+]] { // CHECK-TLS3-NEXT: entry: -// CHECK-TLS3-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG120:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR3:[0-9]+]], !dbg [[DBG122:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG123:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG119:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR3:[0-9]+]], !dbg [[DBG121:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG122:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S1C1Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 !dbg [[DBG124:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 !dbg [[DBG123:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META125:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META124:![0-9]+]], metadata !DIExpression()), !dbg [[DBG126:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META128:![0-9]+]], metadata !DIExpression()), !dbg [[DBG129:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG130:![0-9]+]] -// CHECK-TLS3-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG130]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG131:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG129:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG129]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG130:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S1D1Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG132:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG131:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META133:![0-9]+]], metadata !DIExpression()), !dbg [[DBG134:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]], !dbg [[DBG135:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG136:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]], !dbg [[DBG134:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG135:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S1C2Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG137:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG136:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META138:![0-9]+]], metadata !DIExpression()), !dbg [[DBG139:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META137:![0-9]+]], metadata !DIExpression()), !dbg [[DBG138:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META140:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META139:![0-9]+]], metadata !DIExpression()), !dbg [[DBG140:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG142:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG143:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG142]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG144:![0-9]+]] +// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG141:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG142:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG141]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG143:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S1D2Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG145:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG144:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META146:![0-9]+]], metadata !DIExpression()), !dbg [[DBG147:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META145:![0-9]+]], metadata !DIExpression()), !dbg [[DBG146:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG148:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG150:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG151:![0-9]+]] +// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG147:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG149:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG150:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 -// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG152:![0-9]+]] { +// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG151:![0-9]+]] { // CHECK-TLS3-NEXT: entry: -// CHECK-TLS3-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG153:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG155:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG156:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG152:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG154:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG155:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S2C1Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG157:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG156:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META158:![0-9]+]], metadata !DIExpression()), !dbg [[DBG160:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META157:![0-9]+]], metadata !DIExpression()), !dbg [[DBG159:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META161:![0-9]+]], metadata !DIExpression()), !dbg [[DBG162:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META160:![0-9]+]], metadata !DIExpression()), !dbg [[DBG161:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG163:![0-9]+]] -// CHECK-TLS3-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG163]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG164:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG162:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG162]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG163:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S2D1Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG165:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG164:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META166:![0-9]+]], metadata !DIExpression()), !dbg [[DBG167:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META165:![0-9]+]], metadata !DIExpression()), !dbg [[DBG166:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR3]], !dbg [[DBG168:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG169:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR3]], !dbg [[DBG167:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG168:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S2C2Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG170:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG169:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG172:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META170:![0-9]+]], metadata !DIExpression()), !dbg [[DBG171:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META173:![0-9]+]], metadata !DIExpression()), !dbg [[DBG174:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG173:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG175:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG176:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG175]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG177:![0-9]+]] +// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG174:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG175:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG174]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG176:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S2D2Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG178:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG177:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META179:![0-9]+]], metadata !DIExpression()), !dbg [[DBG180:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META178:![0-9]+]], metadata !DIExpression()), !dbg [[DBG179:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG181:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG183:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG184:![0-9]+]] +// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG180:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG182:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG183:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@__cxx_global_var_init.2 -// CHECK-TLS3-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG185:![0-9]+]] { +// CHECK-TLS3-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG184:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: [[ARRAYINIT_ENDOFINIT5:%.*]] = alloca ptr, align 8 -// CHECK-TLS3-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG186:![0-9]+]] -// CHECK-TLS3-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG188:![0-9]+]] +// CHECK-TLS3-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG185:![0-9]+]] +// CHECK-TLS3-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG187:![0-9]+]] // CHECK-TLS3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// CHECK-TLS3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG189:![0-9]+]] +// CHECK-TLS3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG188:![0-9]+]] // CHECK-TLS3: invoke.cont: -// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG188]] +// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG187]] // CHECK-TLS3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// CHECK-TLS3-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG190:![0-9]+]] +// CHECK-TLS3-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG189:![0-9]+]] // CHECK-TLS3: invoke.cont2: -// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG188]] +// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG187]] // CHECK-TLS3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// CHECK-TLS3-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG191:![0-9]+]] +// CHECK-TLS3-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG190:![0-9]+]] // CHECK-TLS3: invoke.cont3: -// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG192:![0-9]+]] +// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG191:![0-9]+]] // CHECK-TLS3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// CHECK-TLS3-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG193:![0-9]+]] +// CHECK-TLS3-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG192:![0-9]+]] // CHECK-TLS3: invoke.cont7: -// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG192]] +// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG191]] // CHECK-TLS3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// CHECK-TLS3-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG194:![0-9]+]] +// CHECK-TLS3-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG193:![0-9]+]] // CHECK-TLS3: invoke.cont8: -// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG192]] +// CHECK-TLS3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG191]] // CHECK-TLS3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// CHECK-TLS3-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG195:![0-9]+]] +// CHECK-TLS3-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG194:![0-9]+]] // CHECK-TLS3: invoke.cont9: -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG196:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG195:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG195]] // CHECK-TLS3: lpad: // CHECK-TLS3-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS3-NEXT: cleanup, !dbg [[DBG197:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG188]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG188]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG188]] +// CHECK-TLS3-NEXT: cleanup, !dbg [[DBG196:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG187]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG187]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG187]] // CHECK-TLS3: arraydestroy.body: -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG188]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG188]] -// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG188]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG188]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG188]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG187]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG187]] +// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG187]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG187]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG187]] // CHECK-TLS3: arraydestroy.done4: -// CHECK-TLS3-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG188]] +// CHECK-TLS3-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG187]] // CHECK-TLS3: lpad6: // CHECK-TLS3-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS3-NEXT: cleanup, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG197]] -// CHECK-TLS3-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG192]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG192]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG192]] +// CHECK-TLS3-NEXT: cleanup, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG196]] +// CHECK-TLS3-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG191]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG191]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG191]] // CHECK-TLS3: arraydestroy.body11: -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG192]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG192]] -// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR3]], !dbg [[DBG192]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG192]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG192]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG191]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG191]] +// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR3]], !dbg [[DBG191]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG191]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG191]] // CHECK-TLS3: arraydestroy.done15: -// CHECK-TLS3-NEXT: br label [[EHCLEANUP]], !dbg [[DBG192]] +// CHECK-TLS3-NEXT: br label [[EHCLEANUP]], !dbg [[DBG191]] // CHECK-TLS3: ehcleanup: -// CHECK-TLS3-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG186]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG186]] +// CHECK-TLS3-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG185]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG185]] // CHECK-TLS3: arraydestroy.body17: -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]], !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG186]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]], !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG185]] // CHECK-TLS3: arraydestroy.done21: -// CHECK-TLS3-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG186]] +// CHECK-TLS3-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG185]] // CHECK-TLS3: eh.resume: -// CHECK-TLS3-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG186]] -// CHECK-TLS3-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG186]] +// CHECK-TLS3-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG185]] +// CHECK-TLS3-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG185]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// CHECK-TLS3-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG198:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG197:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META202:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203:![0-9]+]] -// CHECK-TLS3-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG203]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META201:![0-9]+]], metadata !DIExpression()), !dbg [[DBG202:![0-9]+]] +// CHECK-TLS3-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG202]] // CHECK-TLS3: arraydestroy.body: -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG203]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG203]] -// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG203]] -// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG203]] -// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG203]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG202]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG202]] +// CHECK-TLS3-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG202]] +// CHECK-TLS3-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG202]] +// CHECK-TLS3-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG202]] // CHECK-TLS3: arraydestroy.done1: -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG203]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG202]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@main @@ -4620,72 +4620,72 @@ int foobar() { // CHECK-TLS3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: [[RES:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG205:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVZ4mainE2sm, align 1, !dbg [[DBG206:![0-9]+]] -// CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG206]] -// CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG206]], !prof [[PROF207:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META203:![0-9]+]], metadata !DIExpression()), !dbg [[DBG204:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVZ4mainE2sm, align 1, !dbg [[DBG205:![0-9]+]] +// CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG205]] +// CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG205]], !prof [[PROF206:![0-9]+]] // CHECK-TLS3: init.check: -// CHECK-TLS3-NEXT: [[TMP1:%.*]] = call ptr @_ZTWL3gs1(), !dbg [[DBG208:![0-9]+]] -// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i32 0, i32 0, !dbg [[DBG209:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG209]] -// CHECK-TLS3-NEXT: call void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP2]]), !dbg [[DBG210:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP3:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG206]] -// CHECK-TLS3-NEXT: store i8 1, ptr @_ZGVZ4mainE2sm, align 1, !dbg [[DBG206]] -// CHECK-TLS3-NEXT: br label [[INIT_END]], !dbg [[DBG206]] +// CHECK-TLS3-NEXT: [[TMP1:%.*]] = call ptr @_ZTWL3gs1(), !dbg [[DBG207:![0-9]+]] +// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i32 0, i32 0, !dbg [[DBG208:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG208]] +// CHECK-TLS3-NEXT: call void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP2]]), !dbg [[DBG209:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP3:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG205]] +// CHECK-TLS3-NEXT: store i8 1, ptr @_ZGVZ4mainE2sm, align 1, !dbg [[DBG205]] +// CHECK-TLS3-NEXT: br label [[INIT_END]], !dbg [[DBG205]] // CHECK-TLS3: init.end: -// CHECK-TLS3-NEXT: [[TMP4:%.*]] = call ptr @_ZTWN6Static1sE(), !dbg [[DBG211:![0-9]+]] -// CHECK-TLS3-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP4]], i32 0, i32 0, !dbg [[DBG212:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP5:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG212]] -// CHECK-TLS3-NEXT: store i32 [[TMP5]], ptr [[RES]], align 4, !dbg [[DBG213:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP6:%.*]] = call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @_ZZ4mainE2sm), !dbg [[DBG214:![0-9]+]] -// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[TMP6]], i32 0, i32 0, !dbg [[DBG215:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP7:%.*]] = load i32, ptr [[A2]], align 8, !dbg [[DBG215]] -// CHECK-TLS3-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG216:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG216]] -// CHECK-TLS3-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG216]] -// CHECK-TLS3-NEXT: [[TMP9:%.*]] = call ptr @_ZTWL3gs1(), !dbg [[DBG217:![0-9]+]] -// CHECK-TLS3-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP9]], i32 0, i32 0, !dbg [[DBG218:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP10:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG218]] -// CHECK-TLS3-NEXT: [[TMP11:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG219:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP11]], [[TMP10]], !dbg [[DBG219]] -// CHECK-TLS3-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG219]] -// CHECK-TLS3-NEXT: [[TMP12:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG220:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP13:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG221:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP13]], [[TMP12]], !dbg [[DBG221]] -// CHECK-TLS3-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG221]] -// CHECK-TLS3-NEXT: [[TMP14:%.*]] = call ptr @_ZTW3gs3(), !dbg [[DBG222:![0-9]+]] -// CHECK-TLS3-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP14]], i32 0, i32 0, !dbg [[DBG223:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP15:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG223]] -// CHECK-TLS3-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG224:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG224]] -// CHECK-TLS3-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG224]] -// CHECK-TLS3-NEXT: [[TMP17:%.*]] = call ptr @_ZTW5arr_x(), !dbg [[DBG225:![0-9]+]] -// CHECK-TLS3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP17]], i64 0, i64 1, !dbg [[DBG225]] -// CHECK-TLS3-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG225]] -// CHECK-TLS3-NEXT: [[A9:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX8]], i32 0, i32 0, !dbg [[DBG226:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP18:%.*]] = load i32, ptr [[A9]], align 4, !dbg [[DBG226]] -// CHECK-TLS3-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG227:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP19]], [[TMP18]], !dbg [[DBG227]] -// CHECK-TLS3-NEXT: store i32 [[ADD10]], ptr [[RES]], align 4, !dbg [[DBG227]] -// CHECK-TLS3-NEXT: [[TMP20:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIiE2stE), !dbg [[DBG228:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4, !dbg [[DBG228]] -// CHECK-TLS3-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG229:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG229]] -// CHECK-TLS3-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG229]] -// CHECK-TLS3-NEXT: [[TMP23:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIfE2stE), !dbg [[DBG230:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP24:%.*]] = load float, ptr [[TMP23]], align 4, !dbg [[DBG230]] -// CHECK-TLS3-NEXT: [[CONV:%.*]] = fptosi float [[TMP24]] to i32, !dbg [[DBG230]] -// CHECK-TLS3-NEXT: [[TMP25:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP25]], [[CONV]], !dbg [[DBG231]] -// CHECK-TLS3-NEXT: store i32 [[ADD12]], ptr [[RES]], align 4, !dbg [[DBG231]] -// CHECK-TLS3-NEXT: [[TMP26:%.*]] = call ptr @_ZTWN2STI2S4E2stE(), !dbg [[DBG232:![0-9]+]] -// CHECK-TLS3-NEXT: [[A13:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP26]], i32 0, i32 0, !dbg [[DBG233:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP27:%.*]] = load i32, ptr [[A13]], align 4, !dbg [[DBG233]] -// CHECK-TLS3-NEXT: [[TMP28:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG234:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP28]], [[TMP27]], !dbg [[DBG234]] -// CHECK-TLS3-NEXT: store i32 [[ADD14]], ptr [[RES]], align 4, !dbg [[DBG234]] -// CHECK-TLS3-NEXT: [[TMP29:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG235:![0-9]+]] -// CHECK-TLS3-NEXT: ret i32 [[TMP29]], !dbg [[DBG236:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP4:%.*]] = call ptr @_ZTWN6Static1sE(), !dbg [[DBG210:![0-9]+]] +// CHECK-TLS3-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP4]], i32 0, i32 0, !dbg [[DBG211:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP5:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG211]] +// CHECK-TLS3-NEXT: store i32 [[TMP5]], ptr [[RES]], align 4, !dbg [[DBG212:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP6:%.*]] = call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @_ZZ4mainE2sm), !dbg [[DBG213:![0-9]+]] +// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[TMP6]], i32 0, i32 0, !dbg [[DBG214:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP7:%.*]] = load i32, ptr [[A2]], align 8, !dbg [[DBG214]] +// CHECK-TLS3-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG215:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG215]] +// CHECK-TLS3-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG215]] +// CHECK-TLS3-NEXT: [[TMP9:%.*]] = call ptr @_ZTWL3gs1(), !dbg [[DBG216:![0-9]+]] +// CHECK-TLS3-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP9]], i32 0, i32 0, !dbg [[DBG217:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP10:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG217]] +// CHECK-TLS3-NEXT: [[TMP11:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG218:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP11]], [[TMP10]], !dbg [[DBG218]] +// CHECK-TLS3-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG218]] +// CHECK-TLS3-NEXT: [[TMP12:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG219:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP13:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG220:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP13]], [[TMP12]], !dbg [[DBG220]] +// CHECK-TLS3-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG220]] +// CHECK-TLS3-NEXT: [[TMP14:%.*]] = call ptr @_ZTW3gs3(), !dbg [[DBG221:![0-9]+]] +// CHECK-TLS3-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP14]], i32 0, i32 0, !dbg [[DBG222:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP15:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG222]] +// CHECK-TLS3-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG223:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG223]] +// CHECK-TLS3-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG223]] +// CHECK-TLS3-NEXT: [[TMP17:%.*]] = call ptr @_ZTW5arr_x(), !dbg [[DBG224:![0-9]+]] +// CHECK-TLS3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP17]], i64 0, i64 1, !dbg [[DBG224]] +// CHECK-TLS3-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG224]] +// CHECK-TLS3-NEXT: [[A9:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX8]], i32 0, i32 0, !dbg [[DBG225:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP18:%.*]] = load i32, ptr [[A9]], align 4, !dbg [[DBG225]] +// CHECK-TLS3-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG226:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP19]], [[TMP18]], !dbg [[DBG226]] +// CHECK-TLS3-NEXT: store i32 [[ADD10]], ptr [[RES]], align 4, !dbg [[DBG226]] +// CHECK-TLS3-NEXT: [[TMP20:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIiE2stE), !dbg [[DBG227:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4, !dbg [[DBG227]] +// CHECK-TLS3-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG228:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG228]] +// CHECK-TLS3-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG228]] +// CHECK-TLS3-NEXT: [[TMP23:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIfE2stE), !dbg [[DBG229:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP24:%.*]] = load float, ptr [[TMP23]], align 4, !dbg [[DBG229]] +// CHECK-TLS3-NEXT: [[CONV:%.*]] = fptosi float [[TMP24]] to i32, !dbg [[DBG229]] +// CHECK-TLS3-NEXT: [[TMP25:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG230:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP25]], [[CONV]], !dbg [[DBG230]] +// CHECK-TLS3-NEXT: store i32 [[ADD12]], ptr [[RES]], align 4, !dbg [[DBG230]] +// CHECK-TLS3-NEXT: [[TMP26:%.*]] = call ptr @_ZTWN2STI2S4E2stE(), !dbg [[DBG231:![0-9]+]] +// CHECK-TLS3-NEXT: [[A13:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP26]], i32 0, i32 0, !dbg [[DBG232:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP27:%.*]] = load i32, ptr [[A13]], align 4, !dbg [[DBG232]] +// CHECK-TLS3-NEXT: [[TMP28:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG233:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP28]], [[TMP27]], !dbg [[DBG233]] +// CHECK-TLS3-NEXT: store i32 [[ADD14]], ptr [[RES]], align 4, !dbg [[DBG233]] +// CHECK-TLS3-NEXT: [[TMP29:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG234:![0-9]+]] +// CHECK-TLS3-NEXT: ret i32 [[TMP29]], !dbg [[DBG235:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZTWL3gs1 @@ -4696,29 +4696,29 @@ int foobar() { // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC1Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG237:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG236:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META238:![0-9]+]], metadata !DIExpression()), !dbg [[DBG240:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META237:![0-9]+]], metadata !DIExpression()), !dbg [[DBG239:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META241:![0-9]+]], metadata !DIExpression()), !dbg [[DBG242:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META240:![0-9]+]], metadata !DIExpression()), !dbg [[DBG241:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG243:![0-9]+]] -// CHECK-TLS3-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG243]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG244:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG242:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG242]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG243:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD1Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG245:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG244:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META246:![0-9]+]], metadata !DIExpression()), !dbg [[DBG247:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META245:![0-9]+]], metadata !DIExpression()), !dbg [[DBG246:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR3]], !dbg [[DBG248:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG249:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR3]], !dbg [[DBG247:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG248:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZTWN6Static1sE @@ -4758,174 +4758,174 @@ int foobar() { // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC2Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG250:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG249:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META251:![0-9]+]], metadata !DIExpression()), !dbg [[DBG252:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META250:![0-9]+]], metadata !DIExpression()), !dbg [[DBG251:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META253:![0-9]+]], metadata !DIExpression()), !dbg [[DBG254:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META252:![0-9]+]], metadata !DIExpression()), !dbg [[DBG253:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG255:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG256:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG255]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG257:![0-9]+]] +// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG254:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG255:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG254]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG256:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD2Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG258:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG257:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META259:![0-9]+]], metadata !DIExpression()), !dbg [[DBG260:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META258:![0-9]+]], metadata !DIExpression()), !dbg [[DBG259:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG261:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG263:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG264:![0-9]+]] +// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG260:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG262:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG263:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_Z6foobarv -// CHECK-TLS3-SAME: () #[[ATTR7:[0-9]+]] !dbg [[DBG265:![0-9]+]] { +// CHECK-TLS3-SAME: () #[[ATTR1]] !dbg [[DBG264:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[RES:%.*]] = alloca i32, align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META266:![0-9]+]], metadata !DIExpression()), !dbg [[DBG267:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call ptr @_ZTWN6Static1sE(), !dbg [[DBG268:![0-9]+]] -// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP0]], i32 0, i32 0, !dbg [[DBG269:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG269]] -// CHECK-TLS3-NEXT: store i32 [[TMP1]], ptr [[RES]], align 4, !dbg [[DBG270:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP2:%.*]] = call ptr @_ZTWL3gs1(), !dbg [[DBG271:![0-9]+]] -// CHECK-TLS3-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP2]], i32 0, i32 0, !dbg [[DBG272:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP3:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG272]] -// CHECK-TLS3-NEXT: [[TMP4:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG273:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP3]], !dbg [[DBG273]] -// CHECK-TLS3-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG273]] -// CHECK-TLS3-NEXT: [[TMP5:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG274:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG275:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG275]] -// CHECK-TLS3-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG275]] -// CHECK-TLS3-NEXT: [[TMP7:%.*]] = call ptr @_ZTW3gs3(), !dbg [[DBG276:![0-9]+]] -// CHECK-TLS3-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP7]], i32 0, i32 0, !dbg [[DBG277:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP8:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG277]] -// CHECK-TLS3-NEXT: [[TMP9:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG278:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP9]], [[TMP8]], !dbg [[DBG278]] -// CHECK-TLS3-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG278]] -// CHECK-TLS3-NEXT: [[TMP10:%.*]] = call ptr @_ZTW5arr_x(), !dbg [[DBG279:![0-9]+]] -// CHECK-TLS3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP10]], i64 0, i64 1, !dbg [[DBG279]] -// CHECK-TLS3-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG279]] -// CHECK-TLS3-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX5]], i32 0, i32 0, !dbg [[DBG280:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP11:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG280]] -// CHECK-TLS3-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG281:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG281]] -// CHECK-TLS3-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG281]] -// CHECK-TLS3-NEXT: [[TMP13:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIiE2stE), !dbg [[DBG282:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4, !dbg [[DBG282]] -// CHECK-TLS3-NEXT: [[TMP15:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG283:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP15]], [[TMP14]], !dbg [[DBG283]] -// CHECK-TLS3-NEXT: store i32 [[ADD8]], ptr [[RES]], align 4, !dbg [[DBG283]] -// CHECK-TLS3-NEXT: [[TMP16:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIfE2stE), !dbg [[DBG284:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP17:%.*]] = load float, ptr [[TMP16]], align 4, !dbg [[DBG284]] -// CHECK-TLS3-NEXT: [[CONV:%.*]] = fptosi float [[TMP17]] to i32, !dbg [[DBG284]] -// CHECK-TLS3-NEXT: [[TMP18:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG285:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP18]], [[CONV]], !dbg [[DBG285]] -// CHECK-TLS3-NEXT: store i32 [[ADD9]], ptr [[RES]], align 4, !dbg [[DBG285]] -// CHECK-TLS3-NEXT: [[TMP19:%.*]] = call ptr @_ZTWN2STI2S4E2stE(), !dbg [[DBG286:![0-9]+]] -// CHECK-TLS3-NEXT: [[A10:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP19]], i32 0, i32 0, !dbg [[DBG287:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP20:%.*]] = load i32, ptr [[A10]], align 4, !dbg [[DBG287]] -// CHECK-TLS3-NEXT: [[TMP21:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG288:![0-9]+]] -// CHECK-TLS3-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP21]], [[TMP20]], !dbg [[DBG288]] -// CHECK-TLS3-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG288]] -// CHECK-TLS3-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG289:![0-9]+]] -// CHECK-TLS3-NEXT: ret i32 [[TMP22]], !dbg [[DBG290:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META265:![0-9]+]], metadata !DIExpression()), !dbg [[DBG266:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = call ptr @_ZTWN6Static1sE(), !dbg [[DBG267:![0-9]+]] +// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP0]], i32 0, i32 0, !dbg [[DBG268:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG268]] +// CHECK-TLS3-NEXT: store i32 [[TMP1]], ptr [[RES]], align 4, !dbg [[DBG269:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP2:%.*]] = call ptr @_ZTWL3gs1(), !dbg [[DBG270:![0-9]+]] +// CHECK-TLS3-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP2]], i32 0, i32 0, !dbg [[DBG271:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP3:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG271]] +// CHECK-TLS3-NEXT: [[TMP4:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG272:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], [[TMP3]], !dbg [[DBG272]] +// CHECK-TLS3-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG272]] +// CHECK-TLS3-NEXT: [[TMP5:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG273:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG274:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG274]] +// CHECK-TLS3-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG274]] +// CHECK-TLS3-NEXT: [[TMP7:%.*]] = call ptr @_ZTW3gs3(), !dbg [[DBG275:![0-9]+]] +// CHECK-TLS3-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP7]], i32 0, i32 0, !dbg [[DBG276:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP8:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG276]] +// CHECK-TLS3-NEXT: [[TMP9:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG277:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP9]], [[TMP8]], !dbg [[DBG277]] +// CHECK-TLS3-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG277]] +// CHECK-TLS3-NEXT: [[TMP10:%.*]] = call ptr @_ZTW5arr_x(), !dbg [[DBG278:![0-9]+]] +// CHECK-TLS3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP10]], i64 0, i64 1, !dbg [[DBG278]] +// CHECK-TLS3-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG278]] +// CHECK-TLS3-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX5]], i32 0, i32 0, !dbg [[DBG279:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP11:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG279]] +// CHECK-TLS3-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG280:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG280]] +// CHECK-TLS3-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG280]] +// CHECK-TLS3-NEXT: [[TMP13:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIiE2stE), !dbg [[DBG281:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4, !dbg [[DBG281]] +// CHECK-TLS3-NEXT: [[TMP15:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG282:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP15]], [[TMP14]], !dbg [[DBG282]] +// CHECK-TLS3-NEXT: store i32 [[ADD8]], ptr [[RES]], align 4, !dbg [[DBG282]] +// CHECK-TLS3-NEXT: [[TMP16:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN2STIfE2stE), !dbg [[DBG283:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP17:%.*]] = load float, ptr [[TMP16]], align 4, !dbg [[DBG283]] +// CHECK-TLS3-NEXT: [[CONV:%.*]] = fptosi float [[TMP17]] to i32, !dbg [[DBG283]] +// CHECK-TLS3-NEXT: [[TMP18:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG284:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP18]], [[CONV]], !dbg [[DBG284]] +// CHECK-TLS3-NEXT: store i32 [[ADD9]], ptr [[RES]], align 4, !dbg [[DBG284]] +// CHECK-TLS3-NEXT: [[TMP19:%.*]] = call ptr @_ZTWN2STI2S4E2stE(), !dbg [[DBG285:![0-9]+]] +// CHECK-TLS3-NEXT: [[A10:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP19]], i32 0, i32 0, !dbg [[DBG286:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP20:%.*]] = load i32, ptr [[A10]], align 4, !dbg [[DBG286]] +// CHECK-TLS3-NEXT: [[TMP21:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG287:![0-9]+]] +// CHECK-TLS3-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP21]], [[TMP20]], !dbg [[DBG287]] +// CHECK-TLS3-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG287]] +// CHECK-TLS3-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG288:![0-9]+]] +// CHECK-TLS3-NEXT: ret i32 [[TMP22]], !dbg [[DBG289:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@__cxx_global_var_init.3 -// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG291:![0-9]+]] { +// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG290:![0-9]+]] { // CHECK-TLS3-NEXT: entry: -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG292:![0-9]+]] -// CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG292]] -// CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG292]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291:![0-9]+]] +// CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG291]] +// CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG291]] // CHECK-TLS3: init.check: -// CHECK-TLS3-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG292]] -// CHECK-TLS3-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG293:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG292]] -// CHECK-TLS3-NEXT: br label [[INIT_END]], !dbg [[DBG292]] +// CHECK-TLS3-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291]] +// CHECK-TLS3-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG292:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG291]] +// CHECK-TLS3-NEXT: br label [[INIT_END]], !dbg [[DBG291]] // CHECK-TLS3: init.end: -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG295:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG294:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S4C1Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG296:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG295:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META297:![0-9]+]], metadata !DIExpression()), !dbg [[DBG299:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META296:![0-9]+]], metadata !DIExpression()), !dbg [[DBG298:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META300:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META299:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG302:![0-9]+]] -// CHECK-TLS3-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG302]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG303:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG301:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG301]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG302:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S4D1Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG304:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG303:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META305:![0-9]+]], metadata !DIExpression()), !dbg [[DBG306:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META304:![0-9]+]], metadata !DIExpression()), !dbg [[DBG305:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]], !dbg [[DBG307:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG308:![0-9]+]] +// CHECK-TLS3-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]], !dbg [[DBG306:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG307:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S4C2Ei -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG309:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG308:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META310:![0-9]+]], metadata !DIExpression()), !dbg [[DBG311:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META309:![0-9]+]], metadata !DIExpression()), !dbg [[DBG310:![0-9]+]] // CHECK-TLS3-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META312:![0-9]+]], metadata !DIExpression()), !dbg [[DBG313:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META311:![0-9]+]], metadata !DIExpression()), !dbg [[DBG312:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG314:![0-9]+]] -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG315:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG314]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG316:![0-9]+]] +// CHECK-TLS3-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG313:![0-9]+]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG314:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG313]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG315:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_ZN2S4D2Ev -// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG317:![0-9]+]] { +// CHECK-TLS3-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG316:![0-9]+]] { // CHECK-TLS3-NEXT: entry: // CHECK-TLS3-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS3-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META318:![0-9]+]], metadata !DIExpression()), !dbg [[DBG319:![0-9]+]] +// CHECK-TLS3-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META317:![0-9]+]], metadata !DIExpression()), !dbg [[DBG318:![0-9]+]] // CHECK-TLS3-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG320:![0-9]+]] -// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG322:![0-9]+]] -// CHECK-TLS3-NEXT: ret void, !dbg [[DBG323:![0-9]+]] +// CHECK-TLS3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG319:![0-9]+]] +// CHECK-TLS3-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG321:![0-9]+]] +// CHECK-TLS3-NEXT: ret void, !dbg [[DBG322:![0-9]+]] // // // CHECK-TLS3-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG324:![0-9]+]] { +// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG323:![0-9]+]] { // CHECK-TLS3-NEXT: entry: -// CHECK-TLS3-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG326:![0-9]+]] +// CHECK-TLS3-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG325:![0-9]+]] // CHECK-TLS3-NEXT: ret void // // // CHECK-TLS3-LABEL: define {{[^@]+}}@__tls_init -// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG327:![0-9]+]] { +// CHECK-TLS3-SAME: () #[[ATTR0]] !dbg [[DBG326:![0-9]+]] { // CHECK-TLS3-NEXT: entry: -// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i8, ptr @__tls_guard, align 1, !dbg [[DBG328:![0-9]+]] -// CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG328]] -// CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT:%.*]], label [[EXIT:%.*]], !dbg [[DBG328]], !prof [[PROF207]] +// CHECK-TLS3-NEXT: [[TMP0:%.*]] = load i8, ptr @__tls_guard, align 1, !dbg [[DBG327:![0-9]+]] +// CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG327]] +// CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT:%.*]], label [[EXIT:%.*]], !dbg [[DBG327]], !prof [[PROF206]] // CHECK-TLS3: init: -// CHECK-TLS3-NEXT: store i8 1, ptr @__tls_guard, align 1, !dbg [[DBG328]] -// CHECK-TLS3-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG328]] -// CHECK-TLS3-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG328]] -// CHECK-TLS3-NEXT: br label [[EXIT]], !dbg [[DBG328]] +// CHECK-TLS3-NEXT: store i8 1, ptr @__tls_guard, align 1, !dbg [[DBG327]] +// CHECK-TLS3-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG327]] +// CHECK-TLS3-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG327]] +// CHECK-TLS3-NEXT: br label [[EXIT]], !dbg [[DBG327]] // CHECK-TLS3: exit: // CHECK-TLS3-NEXT: ret void // @@ -4936,7 +4936,7 @@ int foobar() { // CHECK-TLS4-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: [[RES:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META116:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META116:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117:![0-9]+]] // CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVZ4mainE2sm, align 1, !dbg [[DBG118:![0-9]+]] // CHECK-TLS4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG118]] // CHECK-TLS4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG118]], !prof [[PROF119:![0-9]+]] @@ -5017,9 +5017,9 @@ int foobar() { // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG152:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG152:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META153:![0-9]+]], metadata !DIExpression()), !dbg [[DBG154:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META153:![0-9]+]], metadata !DIExpression()), !dbg [[DBG154:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG155:![0-9]+]] // CHECK-TLS4-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG155]] @@ -5031,7 +5031,7 @@ int foobar() { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META158:![0-9]+]], metadata !DIExpression()), !dbg [[DBG159:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META158:![0-9]+]], metadata !DIExpression()), !dbg [[DBG159:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // CHECK-TLS4-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR5]], !dbg [[DBG160:![0-9]+]] // CHECK-TLS4-NEXT: ret void, !dbg [[DBG161:![0-9]+]] @@ -5086,10 +5086,10 @@ int foobar() { // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_Z6foobarv -// CHECK-TLS4-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG162:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR3]] !dbg [[DBG162:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[RES:%.*]] = alloca i32, align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META163:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META163:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164:![0-9]+]] // CHECK-TLS4-NEXT: [[TMP0:%.*]] = call ptr @_ZTWN6Static1sE(), !dbg [[DBG165:![0-9]+]] // CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP0]], i32 0, i32 0, !dbg [[DBG166:![0-9]+]] // CHECK-TLS4-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG166]] @@ -5140,354 +5140,354 @@ int foobar() { // // // CHECK-TLS4-LABEL: define {{[^@]+}}@__cxx_global_var_init -// CHECK-TLS4-SAME: () #[[ATTR7:[0-9]+]] !dbg [[DBG188:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG188:![0-9]+]] { // CHECK-TLS4-NEXT: entry: -// CHECK-TLS4-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG192:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG194:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG195:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG191:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG193:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG194:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S1C1Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG196:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG195:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META197:![0-9]+]], metadata !DIExpression()), !dbg [[DBG199:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META196:![0-9]+]], metadata !DIExpression()), !dbg [[DBG198:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META200:![0-9]+]], metadata !DIExpression()), !dbg [[DBG201:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META199:![0-9]+]], metadata !DIExpression()), !dbg [[DBG200:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG202:![0-9]+]] -// CHECK-TLS4-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG202]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG203:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG201:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG201]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG202:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S1D1Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG204:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG203:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META205:![0-9]+]], metadata !DIExpression()), !dbg [[DBG206:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG205:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR5]], !dbg [[DBG207:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG208:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR5]], !dbg [[DBG206:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG207:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S1C2Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG209:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG208:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META210:![0-9]+]], metadata !DIExpression()), !dbg [[DBG211:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META209:![0-9]+]], metadata !DIExpression()), !dbg [[DBG210:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META212:![0-9]+]], metadata !DIExpression()), !dbg [[DBG213:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META211:![0-9]+]], metadata !DIExpression()), !dbg [[DBG212:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG214:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG215:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG214]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG216:![0-9]+]] +// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG213:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG214:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG213]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG215:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S1D2Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG217:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG216:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META218:![0-9]+]], metadata !DIExpression()), !dbg [[DBG219:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META217:![0-9]+]], metadata !DIExpression()), !dbg [[DBG218:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG220:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG222:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG223:![0-9]+]] +// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG219:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG221:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG222:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 -// CHECK-TLS4-SAME: () #[[ATTR7]] !dbg [[DBG224:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR6]] !dbg [[DBG223:![0-9]+]] { // CHECK-TLS4-NEXT: entry: -// CHECK-TLS4-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG225:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG227:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG228:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG224:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG226:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG227:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S2C1Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG229:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG228:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META230:![0-9]+]], metadata !DIExpression()), !dbg [[DBG232:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META229:![0-9]+]], metadata !DIExpression()), !dbg [[DBG231:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META233:![0-9]+]], metadata !DIExpression()), !dbg [[DBG234:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META232:![0-9]+]], metadata !DIExpression()), !dbg [[DBG233:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG235:![0-9]+]] -// CHECK-TLS4-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG235]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG236:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG234:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG234]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG235:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S2D1Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG237:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG236:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META238:![0-9]+]], metadata !DIExpression()), !dbg [[DBG239:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META237:![0-9]+]], metadata !DIExpression()), !dbg [[DBG238:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR5]], !dbg [[DBG240:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG241:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR5]], !dbg [[DBG239:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG240:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S2C2Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG242:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG241:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META243:![0-9]+]], metadata !DIExpression()), !dbg [[DBG244:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META242:![0-9]+]], metadata !DIExpression()), !dbg [[DBG243:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META245:![0-9]+]], metadata !DIExpression()), !dbg [[DBG246:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META244:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG247:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG248:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG247]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG249:![0-9]+]] +// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG246:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG247:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG246]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG248:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S2D2Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG250:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG249:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META251:![0-9]+]], metadata !DIExpression()), !dbg [[DBG252:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META250:![0-9]+]], metadata !DIExpression()), !dbg [[DBG251:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG253:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG255:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG256:![0-9]+]] +// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG252:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG254:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG255:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@__cxx_global_var_init.2 -// CHECK-TLS4-SAME: () #[[ATTR7]] personality ptr @__gxx_personality_v0 !dbg [[DBG257:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR6]] personality ptr @__gxx_personality_v0 !dbg [[DBG256:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: [[ARRAYINIT_ENDOFINIT5:%.*]] = alloca ptr, align 8 -// CHECK-TLS4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG258:![0-9]+]] -// CHECK-TLS4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG260:![0-9]+]] +// CHECK-TLS4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG257:![0-9]+]] +// CHECK-TLS4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG259:![0-9]+]] // CHECK-TLS4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// CHECK-TLS4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG261:![0-9]+]] +// CHECK-TLS4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG260:![0-9]+]] // CHECK-TLS4: invoke.cont: -// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG260]] +// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG259]] // CHECK-TLS4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// CHECK-TLS4-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG262:![0-9]+]] +// CHECK-TLS4-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG261:![0-9]+]] // CHECK-TLS4: invoke.cont2: -// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG260]] +// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG259]] // CHECK-TLS4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// CHECK-TLS4-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG263:![0-9]+]] +// CHECK-TLS4-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG262:![0-9]+]] // CHECK-TLS4: invoke.cont3: -// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG264:![0-9]+]] +// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG263:![0-9]+]] // CHECK-TLS4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// CHECK-TLS4-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG265:![0-9]+]] +// CHECK-TLS4-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG264:![0-9]+]] // CHECK-TLS4: invoke.cont7: -// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG264]] +// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG263]] // CHECK-TLS4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// CHECK-TLS4-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG266:![0-9]+]] +// CHECK-TLS4-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG265:![0-9]+]] // CHECK-TLS4: invoke.cont8: -// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG264]] +// CHECK-TLS4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG263]] // CHECK-TLS4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// CHECK-TLS4-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG267:![0-9]+]] +// CHECK-TLS4-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG266:![0-9]+]] // CHECK-TLS4: invoke.cont9: -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG268:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_thread_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG267:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG267]] // CHECK-TLS4: lpad: // CHECK-TLS4-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS4-NEXT: cleanup, !dbg [[DBG269:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG260]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG260]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG260]] +// CHECK-TLS4-NEXT: cleanup, !dbg [[DBG268:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG259]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG259]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG259]] // CHECK-TLS4: arraydestroy.body: -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG260]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG260]] -// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR5]], !dbg [[DBG260]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG260]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG260]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG259]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG259]] +// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR5]], !dbg [[DBG259]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG259]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG259]] // CHECK-TLS4: arraydestroy.done4: -// CHECK-TLS4-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG260]] +// CHECK-TLS4-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG259]] // CHECK-TLS4: lpad6: // CHECK-TLS4-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// CHECK-TLS4-NEXT: cleanup, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG269]] -// CHECK-TLS4-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG264]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG264]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG264]] +// CHECK-TLS4-NEXT: cleanup, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG268]] +// CHECK-TLS4-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG263]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG263]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG263]] // CHECK-TLS4: arraydestroy.body11: -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG264]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG264]] -// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR5]], !dbg [[DBG264]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG264]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG264]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG263]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG263]] +// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR5]], !dbg [[DBG263]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG263]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG263]] // CHECK-TLS4: arraydestroy.done15: -// CHECK-TLS4-NEXT: br label [[EHCLEANUP]], !dbg [[DBG264]] +// CHECK-TLS4-NEXT: br label [[EHCLEANUP]], !dbg [[DBG263]] // CHECK-TLS4: ehcleanup: -// CHECK-TLS4-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG258]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG258]] +// CHECK-TLS4-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG257]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG257]] // CHECK-TLS4: arraydestroy.body17: -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR5]], !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG258]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR5]], !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG257]] // CHECK-TLS4: arraydestroy.done21: -// CHECK-TLS4-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG258]] +// CHECK-TLS4-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG257]] // CHECK-TLS4: eh.resume: -// CHECK-TLS4-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG258]] -// CHECK-TLS4-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG258]] +// CHECK-TLS4-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG257]] +// CHECK-TLS4-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG257]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// CHECK-TLS4-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR7]] !dbg [[DBG270:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR6]] !dbg [[DBG269:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META274:![0-9]+]], metadata !DIExpression()), !dbg [[DBG275:![0-9]+]] -// CHECK-TLS4-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG275]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META273:![0-9]+]], metadata !DIExpression()), !dbg [[DBG274:![0-9]+]] +// CHECK-TLS4-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG274]] // CHECK-TLS4: arraydestroy.body: -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG275]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG275]] -// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR5]], !dbg [[DBG275]] -// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG275]] -// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG275]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG274]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG274]] +// CHECK-TLS4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR5]], !dbg [[DBG274]] +// CHECK-TLS4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG274]] +// CHECK-TLS4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG274]] // CHECK-TLS4: arraydestroy.done1: -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG275]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG274]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC2Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] align 2 !dbg [[DBG276:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] align 2 !dbg [[DBG275:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META277:![0-9]+]], metadata !DIExpression()), !dbg [[DBG278:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META276:![0-9]+]], metadata !DIExpression()), !dbg [[DBG277:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META279:![0-9]+]], metadata !DIExpression()), !dbg [[DBG280:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META278:![0-9]+]], metadata !DIExpression()), !dbg [[DBG279:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG281:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG282:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG281]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG283:![0-9]+]] +// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG280:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG281:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG280]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG282:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD2Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] align 2 !dbg [[DBG284:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] align 2 !dbg [[DBG283:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META285:![0-9]+]], metadata !DIExpression()), !dbg [[DBG286:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META284:![0-9]+]], metadata !DIExpression()), !dbg [[DBG285:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG287:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG289:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG290:![0-9]+]] +// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG286:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG288:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG289:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@__cxx_global_var_init.3 -// CHECK-TLS4-SAME: () #[[ATTR7]] !dbg [[DBG291:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR6]] !dbg [[DBG290:![0-9]+]] { // CHECK-TLS4-NEXT: entry: -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG292:![0-9]+]] -// CHECK-TLS4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG292]] -// CHECK-TLS4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG292]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291:![0-9]+]] +// CHECK-TLS4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG291]] +// CHECK-TLS4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG291]] // CHECK-TLS4: init.check: -// CHECK-TLS4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG292]] -// CHECK-TLS4-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG293:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG292]] -// CHECK-TLS4-NEXT: br label [[INIT_END]], !dbg [[DBG292]] +// CHECK-TLS4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291]] +// CHECK-TLS4-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG292:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG291]] +// CHECK-TLS4-NEXT: br label [[INIT_END]], !dbg [[DBG291]] // CHECK-TLS4: init.end: -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG295:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG294:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S4C1Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG296:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG295:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META297:![0-9]+]], metadata !DIExpression()), !dbg [[DBG299:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META296:![0-9]+]], metadata !DIExpression()), !dbg [[DBG298:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META300:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META299:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG302:![0-9]+]] -// CHECK-TLS4-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG302]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG303:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG301:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG301]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG302:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S4D1Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG304:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG303:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META305:![0-9]+]], metadata !DIExpression()), !dbg [[DBG306:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META304:![0-9]+]], metadata !DIExpression()), !dbg [[DBG305:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR5]], !dbg [[DBG307:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG308:![0-9]+]] +// CHECK-TLS4-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR5]], !dbg [[DBG306:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG307:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S4C2Ei -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG309:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG308:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META310:![0-9]+]], metadata !DIExpression()), !dbg [[DBG311:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META309:![0-9]+]], metadata !DIExpression()), !dbg [[DBG310:![0-9]+]] // CHECK-TLS4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META312:![0-9]+]], metadata !DIExpression()), !dbg [[DBG313:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META311:![0-9]+]], metadata !DIExpression()), !dbg [[DBG312:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG314:![0-9]+]] -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG315:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG314]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG316:![0-9]+]] +// CHECK-TLS4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG313:![0-9]+]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG314:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG313]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG315:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_ZN2S4D2Ev -// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG317:![0-9]+]] { +// CHECK-TLS4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 !dbg [[DBG316:![0-9]+]] { // CHECK-TLS4-NEXT: entry: // CHECK-TLS4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-TLS4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META318:![0-9]+]], metadata !DIExpression()), !dbg [[DBG319:![0-9]+]] +// CHECK-TLS4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META317:![0-9]+]], metadata !DIExpression()), !dbg [[DBG318:![0-9]+]] // CHECK-TLS4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG320:![0-9]+]] -// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG322:![0-9]+]] -// CHECK-TLS4-NEXT: ret void, !dbg [[DBG323:![0-9]+]] +// CHECK-TLS4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG319:![0-9]+]] +// CHECK-TLS4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG321:![0-9]+]] +// CHECK-TLS4-NEXT: ret void, !dbg [[DBG322:![0-9]+]] // // // CHECK-TLS4-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// CHECK-TLS4-SAME: () #[[ATTR7]] !dbg [[DBG324:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR6]] !dbg [[DBG323:![0-9]+]] { // CHECK-TLS4-NEXT: entry: -// CHECK-TLS4-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG326:![0-9]+]] +// CHECK-TLS4-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG325:![0-9]+]] // CHECK-TLS4-NEXT: ret void // // // CHECK-TLS4-LABEL: define {{[^@]+}}@__tls_init -// CHECK-TLS4-SAME: () #[[ATTR7]] !dbg [[DBG327:![0-9]+]] { +// CHECK-TLS4-SAME: () #[[ATTR6]] !dbg [[DBG326:![0-9]+]] { // CHECK-TLS4-NEXT: entry: -// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i8, ptr @__tls_guard, align 1, !dbg [[DBG328:![0-9]+]] -// CHECK-TLS4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG328]] -// CHECK-TLS4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT:%.*]], label [[EXIT:%.*]], !dbg [[DBG328]], !prof [[PROF119]] +// CHECK-TLS4-NEXT: [[TMP0:%.*]] = load i8, ptr @__tls_guard, align 1, !dbg [[DBG327:![0-9]+]] +// CHECK-TLS4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG327]] +// CHECK-TLS4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT:%.*]], label [[EXIT:%.*]], !dbg [[DBG327]], !prof [[PROF119]] // CHECK-TLS4: init: -// CHECK-TLS4-NEXT: store i8 1, ptr @__tls_guard, align 1, !dbg [[DBG328]] -// CHECK-TLS4-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG328]] -// CHECK-TLS4-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG328]] -// CHECK-TLS4-NEXT: br label [[EXIT]], !dbg [[DBG328]] +// CHECK-TLS4-NEXT: store i8 1, ptr @__tls_guard, align 1, !dbg [[DBG327]] +// CHECK-TLS4-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG327]] +// CHECK-TLS4-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG327]] +// CHECK-TLS4-NEXT: br label [[EXIT]], !dbg [[DBG327]] // CHECK-TLS4: exit: // CHECK-TLS4-NEXT: ret void // @@ -5565,34 +5565,34 @@ int foobar() { // SIMD3-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8 // SIMD3-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // SIMD3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// SIMD3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// SIMD3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // SIMD3: invoke.cont: // SIMD3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // SIMD3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// SIMD3-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] +// SIMD3-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]] // SIMD3: invoke.cont2: // SIMD3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8 // SIMD3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// SIMD3-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] +// SIMD3-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]] // SIMD3: invoke.cont3: // SIMD3-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8 // SIMD3-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // SIMD3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// SIMD3-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] +// SIMD3-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]] // SIMD3: invoke.cont7: // SIMD3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // SIMD3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// SIMD3-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] +// SIMD3-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]] // SIMD3: invoke.cont8: // SIMD3-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8 // SIMD3-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// SIMD3-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] +// SIMD3-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]] // SIMD3: invoke.cont9: // SIMD3-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]] // SIMD3-NEXT: ret void // SIMD3: lpad: // SIMD3-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// SIMD3-NEXT: cleanup +// SIMD3-NEXT: cleanup // SIMD3-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 // SIMD3-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 // SIMD3-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 @@ -5610,7 +5610,7 @@ int foobar() { // SIMD3-NEXT: br label [[EHCLEANUP:%.*]] // SIMD3: lpad6: // SIMD3-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// SIMD3-NEXT: cleanup +// SIMD3-NEXT: cleanup // SIMD3-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0 // SIMD3-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8 // SIMD3-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1 @@ -5681,7 +5681,7 @@ int foobar() { // SIMD3: init: // SIMD3-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZL3gs1, align 4 // SIMD3-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP2]]) -// SIMD3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] +// SIMD3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // SIMD3: invoke.cont: // SIMD3-NEXT: [[TMP3:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]] // SIMD3-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]] @@ -5726,7 +5726,7 @@ int foobar() { // SIMD3-NEXT: ret i32 [[TMP21]] // SIMD3: lpad: // SIMD3-NEXT: [[TMP22:%.*]] = landingpad { ptr, i32 } -// SIMD3-NEXT: cleanup +// SIMD3-NEXT: cleanup // SIMD3-NEXT: [[TMP23:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 0 // SIMD3-NEXT: store ptr [[TMP23]], ptr [[EXN_SLOT]], align 8 // SIMD3-NEXT: [[TMP24:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 1 @@ -5765,7 +5765,7 @@ int foobar() { // // // SIMD3-LABEL: define {{[^@]+}}@_Z6foobarv -// SIMD3-SAME: () #[[ATTR5:[0-9]+]] { +// SIMD3-SAME: () #[[ATTR2]] { // SIMD3-NEXT: entry: // SIMD3-NEXT: [[RES:%.*]] = alloca i32, align 4 // SIMD3-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN6Static1sE, align 4 @@ -5953,179 +5953,179 @@ int foobar() { // SIMD4-LABEL: define {{[^@]+}}@__cxx_global_var_init // SIMD4-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG115:![0-9]+]] { // SIMD4-NEXT: entry: -// SIMD4-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG119:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR3:[0-9]+]], !dbg [[DBG121:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG122:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG118:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR3:[0-9]+]], !dbg [[DBG120:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG121:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S1C1Ei -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 !dbg [[DBG123:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 !dbg [[DBG122:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META124:![0-9]+]], metadata !DIExpression()), !dbg [[DBG126:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META123:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META126:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG129:![0-9]+]] -// SIMD4-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG129]] -// SIMD4-NEXT: ret void, !dbg [[DBG130:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG128:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG128]] +// SIMD4-NEXT: ret void, !dbg [[DBG129:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S1D1Ev -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG131:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG130:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG132:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]], !dbg [[DBG134:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG135:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]], !dbg [[DBG133:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG134:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 -// SIMD4-SAME: () #[[ATTR0]] !dbg [[DBG136:![0-9]+]] { +// SIMD4-SAME: () #[[ATTR0]] !dbg [[DBG135:![0-9]+]] { // SIMD4-NEXT: entry: -// SIMD4-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG137:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG139:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG140:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG136:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG138:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG139:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S2C1Ei -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG141:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG140:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META142:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META141:![0-9]+]], metadata !DIExpression()), !dbg [[DBG143:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META145:![0-9]+]], metadata !DIExpression()), !dbg [[DBG146:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META144:![0-9]+]], metadata !DIExpression()), !dbg [[DBG145:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG147:![0-9]+]] -// SIMD4-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG147]] -// SIMD4-NEXT: ret void, !dbg [[DBG148:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG146:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG146]] +// SIMD4-NEXT: ret void, !dbg [[DBG147:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S2D1Ev -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG149:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG148:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG151:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META149:![0-9]+]], metadata !DIExpression()), !dbg [[DBG150:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR3]], !dbg [[DBG152:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG153:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR3]], !dbg [[DBG151:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG152:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@__cxx_global_var_init.2 -// SIMD4-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG154:![0-9]+]] { +// SIMD4-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG153:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // SIMD4-NEXT: [[ARRAYINIT_ENDOFINIT5:%.*]] = alloca ptr, align 8 -// SIMD4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG155:![0-9]+]] -// SIMD4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157:![0-9]+]] +// SIMD4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG154:![0-9]+]] +// SIMD4-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156:![0-9]+]] // SIMD4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// SIMD4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG158:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG157:![0-9]+]] // SIMD4: invoke.cont: -// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157]] +// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156]] // SIMD4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// SIMD4-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG159:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG158:![0-9]+]] // SIMD4: invoke.cont2: -// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157]] +// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156]] // SIMD4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// SIMD4-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG160:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG159:![0-9]+]] // SIMD4: invoke.cont3: -// SIMD4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG155]] -// SIMD4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161:![0-9]+]] +// SIMD4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG154]] +// SIMD4-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160:![0-9]+]] // SIMD4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// SIMD4-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG162:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG161:![0-9]+]] // SIMD4: invoke.cont7: -// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161]] +// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160]] // SIMD4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// SIMD4-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG163:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG162:![0-9]+]] // SIMD4: invoke.cont8: -// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161]] +// SIMD4-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160]] // SIMD4-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// SIMD4-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG164:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG163:![0-9]+]] // SIMD4: invoke.cont9: -// SIMD4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG165:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG165]] +// SIMD4-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG164:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG164]] // SIMD4: lpad: // SIMD4-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// SIMD4-NEXT: cleanup, !dbg [[DBG166:![0-9]+]] -// SIMD4-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG166]] -// SIMD4-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG166]] -// SIMD4-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG166]] -// SIMD4-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG166]] -// SIMD4-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG157]] -// SIMD4-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG157]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG157]] +// SIMD4-NEXT: cleanup, !dbg [[DBG165:![0-9]+]] +// SIMD4-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG165]] +// SIMD4-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG165]] +// SIMD4-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG165]] +// SIMD4-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG165]] +// SIMD4-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG156]] +// SIMD4-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG156]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG156]] // SIMD4: arraydestroy.body: -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG157]] -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG157]] -// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG157]] -// SIMD4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG157]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG157]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG156]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG156]] +// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG156]] +// SIMD4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG156]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG156]] // SIMD4: arraydestroy.done4: -// SIMD4-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG157]] +// SIMD4-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG156]] // SIMD4: lpad6: // SIMD4-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// SIMD4-NEXT: cleanup, !dbg [[DBG166]] -// SIMD4-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG166]] -// SIMD4-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG166]] -// SIMD4-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG166]] -// SIMD4-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG166]] -// SIMD4-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG161]] -// SIMD4-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG161]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG161]] +// SIMD4-NEXT: cleanup, !dbg [[DBG165]] +// SIMD4-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG165]] +// SIMD4-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG165]] +// SIMD4-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG165]] +// SIMD4-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG165]] +// SIMD4-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG160]] +// SIMD4-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG160]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG160]] // SIMD4: arraydestroy.body11: -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG161]] -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG161]] -// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR3]], !dbg [[DBG161]] -// SIMD4-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG161]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG161]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG160]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG160]] +// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR3]], !dbg [[DBG160]] +// SIMD4-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG160]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG160]] // SIMD4: arraydestroy.done15: -// SIMD4-NEXT: br label [[EHCLEANUP]], !dbg [[DBG161]] +// SIMD4-NEXT: br label [[EHCLEANUP]], !dbg [[DBG160]] // SIMD4: ehcleanup: -// SIMD4-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG155]] -// SIMD4-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG155]] -// SIMD4-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG155]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG155]] +// SIMD4-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG154]] +// SIMD4-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG154]] +// SIMD4-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG154]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG154]] // SIMD4: arraydestroy.body17: -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG155]] -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG155]] -// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]], !dbg [[DBG155]] -// SIMD4-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG155]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG155]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG154]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG154]] +// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR3]], !dbg [[DBG154]] +// SIMD4-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG154]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG154]] // SIMD4: arraydestroy.done21: -// SIMD4-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG155]] +// SIMD4-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG154]] // SIMD4: eh.resume: -// SIMD4-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG155]] -// SIMD4-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG155]] -// SIMD4-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG155]] -// SIMD4-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG155]] -// SIMD4-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG155]] +// SIMD4-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG154]] +// SIMD4-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG154]] +// SIMD4-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG154]] +// SIMD4-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG154]] +// SIMD4-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG154]] // // // SIMD4-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// SIMD4-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG167:![0-9]+]] { +// SIMD4-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG166:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG172:![0-9]+]] -// SIMD4-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG172]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META170:![0-9]+]], metadata !DIExpression()), !dbg [[DBG171:![0-9]+]] +// SIMD4-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG171]] // SIMD4: arraydestroy.body: -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG172]] -// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG172]] -// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG172]] -// SIMD4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG172]] -// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG172]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG171]] +// SIMD4-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG171]] +// SIMD4-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG171]] +// SIMD4-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG171]] +// SIMD4-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG171]] // SIMD4: arraydestroy.done1: -// SIMD4-NEXT: ret void, !dbg [[DBG172]] +// SIMD4-NEXT: ret void, !dbg [[DBG171]] // // // SIMD4-LABEL: define {{[^@]+}}@main @@ -6136,302 +6136,302 @@ int foobar() { // SIMD4-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META173:![0-9]+]], metadata !DIExpression()), !dbg [[DBG174:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = load atomic i8, ptr @_ZGVZ4mainE2sm acquire, align 8, !dbg [[DBG175:![0-9]+]] -// SIMD4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG175]] -// SIMD4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG175]], !prof [[PROF176:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG173:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load atomic i8, ptr @_ZGVZ4mainE2sm acquire, align 8, !dbg [[DBG174:![0-9]+]] +// SIMD4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG174]] +// SIMD4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG174]], !prof [[PROF175:![0-9]+]] // SIMD4: init.check: -// SIMD4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG175]] -// SIMD4-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0, !dbg [[DBG175]] -// SIMD4-NEXT: br i1 [[TOBOOL]], label [[INIT:%.*]], label [[INIT_END]], !dbg [[DBG175]] +// SIMD4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG174]] +// SIMD4-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0, !dbg [[DBG174]] +// SIMD4-NEXT: br i1 [[TOBOOL]], label [[INIT:%.*]], label [[INIT_END]], !dbg [[DBG174]] // SIMD4: init: -// SIMD4-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG177:![0-9]+]] +// SIMD4-NEXT: [[TMP2:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG176:![0-9]+]] // SIMD4-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP2]]) -// SIMD4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG178:![0-9]+]] +// SIMD4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG177:![0-9]+]] // SIMD4: invoke.cont: -// SIMD4-NEXT: [[TMP3:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG175]] -// SIMD4-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG175]] -// SIMD4-NEXT: br label [[INIT_END]], !dbg [[DBG175]] +// SIMD4-NEXT: [[TMP3:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG174]] +// SIMD4-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG174]] +// SIMD4-NEXT: br label [[INIT_END]], !dbg [[DBG174]] // SIMD4: init.end: -// SIMD4-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG179:![0-9]+]] -// SIMD4-NEXT: store i32 [[TMP4]], ptr [[RES]], align 4, !dbg [[DBG180:![0-9]+]] -// SIMD4-NEXT: [[TMP5:%.*]] = load i32, ptr @_ZZ4mainE2sm, align 8, !dbg [[DBG181:![0-9]+]] -// SIMD4-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG182:![0-9]+]] -// SIMD4-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG182]] -// SIMD4-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG182]] -// SIMD4-NEXT: [[TMP7:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG183:![0-9]+]] -// SIMD4-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG184:![0-9]+]] -// SIMD4-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG184]] -// SIMD4-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG184]] -// SIMD4-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG185:![0-9]+]] -// SIMD4-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG186:![0-9]+]] -// SIMD4-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG186]] -// SIMD4-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG186]] -// SIMD4-NEXT: [[TMP11:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG187:![0-9]+]] -// SIMD4-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG188:![0-9]+]] -// SIMD4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG188]] -// SIMD4-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG188]] -// SIMD4-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG189:![0-9]+]] -// SIMD4-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG190:![0-9]+]] -// SIMD4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG190]] -// SIMD4-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG190]] -// SIMD4-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG191:![0-9]+]] -// SIMD4-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG192:![0-9]+]] -// SIMD4-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG192]] -// SIMD4-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG192]] -// SIMD4-NEXT: [[TMP17:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG193:![0-9]+]] -// SIMD4-NEXT: [[CONV:%.*]] = fptosi float [[TMP17]] to i32, !dbg [[DBG193]] -// SIMD4-NEXT: [[TMP18:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG194:![0-9]+]] -// SIMD4-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP18]], [[CONV]], !dbg [[DBG194]] -// SIMD4-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG194]] -// SIMD4-NEXT: [[TMP19:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG195:![0-9]+]] -// SIMD4-NEXT: [[TMP20:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG196:![0-9]+]] -// SIMD4-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP20]], [[TMP19]], !dbg [[DBG196]] -// SIMD4-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG196]] -// SIMD4-NEXT: [[TMP21:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG197:![0-9]+]] -// SIMD4-NEXT: ret i32 [[TMP21]], !dbg [[DBG198:![0-9]+]] +// SIMD4-NEXT: [[TMP4:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG178:![0-9]+]] +// SIMD4-NEXT: store i32 [[TMP4]], ptr [[RES]], align 4, !dbg [[DBG179:![0-9]+]] +// SIMD4-NEXT: [[TMP5:%.*]] = load i32, ptr @_ZZ4mainE2sm, align 8, !dbg [[DBG180:![0-9]+]] +// SIMD4-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG181:![0-9]+]] +// SIMD4-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG181]] +// SIMD4-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG181]] +// SIMD4-NEXT: [[TMP7:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG182:![0-9]+]] +// SIMD4-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG183:![0-9]+]] +// SIMD4-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG183]] +// SIMD4-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG183]] +// SIMD4-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG184:![0-9]+]] +// SIMD4-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG185:![0-9]+]] +// SIMD4-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG185]] +// SIMD4-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG185]] +// SIMD4-NEXT: [[TMP11:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG186:![0-9]+]] +// SIMD4-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG187:![0-9]+]] +// SIMD4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP12]], [[TMP11]], !dbg [[DBG187]] +// SIMD4-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG187]] +// SIMD4-NEXT: [[TMP13:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG188:![0-9]+]] +// SIMD4-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG189:![0-9]+]] +// SIMD4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG189]] +// SIMD4-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG189]] +// SIMD4-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG190:![0-9]+]] +// SIMD4-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG191:![0-9]+]] +// SIMD4-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG191]] +// SIMD4-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG191]] +// SIMD4-NEXT: [[TMP17:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG192:![0-9]+]] +// SIMD4-NEXT: [[CONV:%.*]] = fptosi float [[TMP17]] to i32, !dbg [[DBG192]] +// SIMD4-NEXT: [[TMP18:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG193:![0-9]+]] +// SIMD4-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP18]], [[CONV]], !dbg [[DBG193]] +// SIMD4-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG193]] +// SIMD4-NEXT: [[TMP19:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG194:![0-9]+]] +// SIMD4-NEXT: [[TMP20:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG195:![0-9]+]] +// SIMD4-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP20]], [[TMP19]], !dbg [[DBG195]] +// SIMD4-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG195]] +// SIMD4-NEXT: [[TMP21:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG196:![0-9]+]] +// SIMD4-NEXT: ret i32 [[TMP21]], !dbg [[DBG197:![0-9]+]] // SIMD4: lpad: // SIMD4-NEXT: [[TMP22:%.*]] = landingpad { ptr, i32 } -// SIMD4-NEXT: cleanup, !dbg [[DBG199:![0-9]+]] -// SIMD4-NEXT: [[TMP23:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 0, !dbg [[DBG199]] -// SIMD4-NEXT: store ptr [[TMP23]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG199]] -// SIMD4-NEXT: [[TMP24:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 1, !dbg [[DBG199]] -// SIMD4-NEXT: store i32 [[TMP24]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG199]] -// SIMD4-NEXT: call void @__cxa_guard_abort(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG175]] -// SIMD4-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG175]] +// SIMD4-NEXT: cleanup, !dbg [[DBG198:![0-9]+]] +// SIMD4-NEXT: [[TMP23:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 0, !dbg [[DBG198]] +// SIMD4-NEXT: store ptr [[TMP23]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG198]] +// SIMD4-NEXT: [[TMP24:%.*]] = extractvalue { ptr, i32 } [[TMP22]], 1, !dbg [[DBG198]] +// SIMD4-NEXT: store i32 [[TMP24]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG198]] +// SIMD4-NEXT: call void @__cxa_guard_abort(ptr @_ZGVZ4mainE2sm) #[[ATTR3]], !dbg [[DBG174]] +// SIMD4-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG174]] // SIMD4: eh.resume: -// SIMD4-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG175]] -// SIMD4-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG175]] -// SIMD4-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG175]] -// SIMD4-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG175]] -// SIMD4-NEXT: resume { ptr, i32 } [[LPAD_VAL8]], !dbg [[DBG175]] +// SIMD4-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG174]] +// SIMD4-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG174]] +// SIMD4-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG174]] +// SIMD4-NEXT: [[LPAD_VAL8:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG174]] +// SIMD4-NEXT: resume { ptr, i32 } [[LPAD_VAL8]], !dbg [[DBG174]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC1Ei -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG200:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG199:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META201:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META200:![0-9]+]], metadata !DIExpression()), !dbg [[DBG202:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG205:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META203:![0-9]+]], metadata !DIExpression()), !dbg [[DBG204:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG206:![0-9]+]] -// SIMD4-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG206]] -// SIMD4-NEXT: ret void, !dbg [[DBG207:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG205:![0-9]+]] +// SIMD4-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG205]] +// SIMD4-NEXT: ret void, !dbg [[DBG206:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD1Ev -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG208:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG207:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META209:![0-9]+]], metadata !DIExpression()), !dbg [[DBG210:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META208:![0-9]+]], metadata !DIExpression()), !dbg [[DBG209:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR3]], !dbg [[DBG211:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG212:![0-9]+]] +// SIMD4-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR3]], !dbg [[DBG210:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG211:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_Z6foobarv -// SIMD4-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG213:![0-9]+]] { +// SIMD4-SAME: () #[[ATTR2]] !dbg [[DBG212:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[RES:%.*]] = alloca i32, align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META214:![0-9]+]], metadata !DIExpression()), !dbg [[DBG215:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG216:![0-9]+]] -// SIMD4-NEXT: store i32 [[TMP0]], ptr [[RES]], align 4, !dbg [[DBG217:![0-9]+]] -// SIMD4-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG218:![0-9]+]] -// SIMD4-NEXT: [[TMP2:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG219:![0-9]+]] -// SIMD4-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]], !dbg [[DBG219]] -// SIMD4-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG219]] -// SIMD4-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG220:![0-9]+]] -// SIMD4-NEXT: [[TMP4:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG221:![0-9]+]] -// SIMD4-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], [[TMP3]], !dbg [[DBG221]] -// SIMD4-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG221]] -// SIMD4-NEXT: [[TMP5:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG222:![0-9]+]] -// SIMD4-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG223:![0-9]+]] -// SIMD4-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG223]] -// SIMD4-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG223]] -// SIMD4-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG224:![0-9]+]] -// SIMD4-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG225:![0-9]+]] -// SIMD4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG225]] -// SIMD4-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG225]] -// SIMD4-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG226:![0-9]+]] -// SIMD4-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG227:![0-9]+]] -// SIMD4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG227]] -// SIMD4-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG227]] -// SIMD4-NEXT: [[TMP11:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG228:![0-9]+]] -// SIMD4-NEXT: [[CONV:%.*]] = fptosi float [[TMP11]] to i32, !dbg [[DBG228]] -// SIMD4-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG229:![0-9]+]] -// SIMD4-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP12]], [[CONV]], !dbg [[DBG229]] -// SIMD4-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG229]] -// SIMD4-NEXT: [[TMP13:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG230:![0-9]+]] -// SIMD4-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] -// SIMD4-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG231]] -// SIMD4-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG231]] -// SIMD4-NEXT: [[TMP15:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG232:![0-9]+]] -// SIMD4-NEXT: ret i32 [[TMP15]], !dbg [[DBG233:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META213:![0-9]+]], metadata !DIExpression()), !dbg [[DBG214:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr @_ZN6Static1sE, align 4, !dbg [[DBG215:![0-9]+]] +// SIMD4-NEXT: store i32 [[TMP0]], ptr [[RES]], align 4, !dbg [[DBG216:![0-9]+]] +// SIMD4-NEXT: [[TMP1:%.*]] = load i32, ptr @_ZL3gs1, align 4, !dbg [[DBG217:![0-9]+]] +// SIMD4-NEXT: [[TMP2:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG218:![0-9]+]] +// SIMD4-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[TMP1]], !dbg [[DBG218]] +// SIMD4-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG218]] +// SIMD4-NEXT: [[TMP3:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG219:![0-9]+]] +// SIMD4-NEXT: [[TMP4:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG220:![0-9]+]] +// SIMD4-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], [[TMP3]], !dbg [[DBG220]] +// SIMD4-NEXT: store i32 [[ADD1]], ptr [[RES]], align 4, !dbg [[DBG220]] +// SIMD4-NEXT: [[TMP5:%.*]] = load i32, ptr @gs3, align 4, !dbg [[DBG221:![0-9]+]] +// SIMD4-NEXT: [[TMP6:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG222:![0-9]+]] +// SIMD4-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP6]], [[TMP5]], !dbg [[DBG222]] +// SIMD4-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG222]] +// SIMD4-NEXT: [[TMP7:%.*]] = load i32, ptr getelementptr inbounds ([2 x [3 x %struct.S1]], ptr @arr_x, i64 0, i64 1, i64 1), align 4, !dbg [[DBG223:![0-9]+]] +// SIMD4-NEXT: [[TMP8:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG224:![0-9]+]] +// SIMD4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], [[TMP7]], !dbg [[DBG224]] +// SIMD4-NEXT: store i32 [[ADD3]], ptr [[RES]], align 4, !dbg [[DBG224]] +// SIMD4-NEXT: [[TMP9:%.*]] = load i32, ptr @_ZN2STIiE2stE, align 4, !dbg [[DBG225:![0-9]+]] +// SIMD4-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG226:![0-9]+]] +// SIMD4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG226]] +// SIMD4-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG226]] +// SIMD4-NEXT: [[TMP11:%.*]] = load float, ptr @_ZN2STIfE2stE, align 4, !dbg [[DBG227:![0-9]+]] +// SIMD4-NEXT: [[CONV:%.*]] = fptosi float [[TMP11]] to i32, !dbg [[DBG227]] +// SIMD4-NEXT: [[TMP12:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG228:![0-9]+]] +// SIMD4-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP12]], [[CONV]], !dbg [[DBG228]] +// SIMD4-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG228]] +// SIMD4-NEXT: [[TMP13:%.*]] = load i32, ptr @_ZN2STI2S4E2stE, align 4, !dbg [[DBG229:![0-9]+]] +// SIMD4-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG230:![0-9]+]] +// SIMD4-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG230]] +// SIMD4-NEXT: store i32 [[ADD6]], ptr [[RES]], align 4, !dbg [[DBG230]] +// SIMD4-NEXT: [[TMP15:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] +// SIMD4-NEXT: ret i32 [[TMP15]], !dbg [[DBG232:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@__cxx_global_var_init.3 -// SIMD4-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG234:![0-9]+]] { +// SIMD4-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG233:![0-9]+]] { // SIMD4-NEXT: entry: -// SIMD4-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG235:![0-9]+]] -// SIMD4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG235]] -// SIMD4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG235]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234:![0-9]+]] +// SIMD4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG234]] +// SIMD4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG234]] // SIMD4: init.check: -// SIMD4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG235]] -// SIMD4-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG236:![0-9]+]] -// SIMD4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG235]] -// SIMD4-NEXT: br label [[INIT_END]], !dbg [[DBG235]] +// SIMD4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234]] +// SIMD4-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG235:![0-9]+]] +// SIMD4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG234]] +// SIMD4-NEXT: br label [[INIT_END]], !dbg [[DBG234]] // SIMD4: init.end: -// SIMD4-NEXT: ret void, !dbg [[DBG238:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG237:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S4C1Ei -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG239:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 !dbg [[DBG238:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META240:![0-9]+]], metadata !DIExpression()), !dbg [[DBG242:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META239:![0-9]+]], metadata !DIExpression()), !dbg [[DBG241:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META243:![0-9]+]], metadata !DIExpression()), !dbg [[DBG244:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META242:![0-9]+]], metadata !DIExpression()), !dbg [[DBG243:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG245:![0-9]+]] -// SIMD4-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG245]] -// SIMD4-NEXT: ret void, !dbg [[DBG246:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG244:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG244]] +// SIMD4-NEXT: ret void, !dbg [[DBG245:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S4D1Ev -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG247:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG246:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META248:![0-9]+]], metadata !DIExpression()), !dbg [[DBG249:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META247:![0-9]+]], metadata !DIExpression()), !dbg [[DBG248:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]], !dbg [[DBG250:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG251:![0-9]+]] +// SIMD4-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]], !dbg [[DBG249:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG250:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S1C2Ei -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG252:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG251:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META253:![0-9]+]], metadata !DIExpression()), !dbg [[DBG254:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META252:![0-9]+]], metadata !DIExpression()), !dbg [[DBG253:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META255:![0-9]+]], metadata !DIExpression()), !dbg [[DBG256:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META254:![0-9]+]], metadata !DIExpression()), !dbg [[DBG255:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG257:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG258:![0-9]+]] -// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG257]] -// SIMD4-NEXT: ret void, !dbg [[DBG259:![0-9]+]] +// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG256:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG257:![0-9]+]] +// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG256]] +// SIMD4-NEXT: ret void, !dbg [[DBG258:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S1D2Ev -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG260:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG259:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META261:![0-9]+]], metadata !DIExpression()), !dbg [[DBG262:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META260:![0-9]+]], metadata !DIExpression()), !dbg [[DBG261:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG263:![0-9]+]] -// SIMD4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG265:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG266:![0-9]+]] +// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG262:![0-9]+]] +// SIMD4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG264:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG265:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S2C2Ei -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG267:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG266:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META268:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META267:![0-9]+]], metadata !DIExpression()), !dbg [[DBG268:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META270:![0-9]+]], metadata !DIExpression()), !dbg [[DBG271:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META269:![0-9]+]], metadata !DIExpression()), !dbg [[DBG270:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG272:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG273:![0-9]+]] -// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG272]] -// SIMD4-NEXT: ret void, !dbg [[DBG274:![0-9]+]] +// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG271:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG272:![0-9]+]] +// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG271]] +// SIMD4-NEXT: ret void, !dbg [[DBG273:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S2D2Ev -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG275:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG274:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META276:![0-9]+]], metadata !DIExpression()), !dbg [[DBG277:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META275:![0-9]+]], metadata !DIExpression()), !dbg [[DBG276:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG278:![0-9]+]] -// SIMD4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG280:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG281:![0-9]+]] +// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG277:![0-9]+]] +// SIMD4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG279:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG280:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC2Ei -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG282:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG281:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META283:![0-9]+]], metadata !DIExpression()), !dbg [[DBG284:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META282:![0-9]+]], metadata !DIExpression()), !dbg [[DBG283:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META285:![0-9]+]], metadata !DIExpression()), !dbg [[DBG286:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META284:![0-9]+]], metadata !DIExpression()), !dbg [[DBG285:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG287:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG288:![0-9]+]] -// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG287]] -// SIMD4-NEXT: ret void, !dbg [[DBG289:![0-9]+]] +// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG286:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG287:![0-9]+]] +// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG286]] +// SIMD4-NEXT: ret void, !dbg [[DBG288:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD2Ev -// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG290:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG289:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META291:![0-9]+]], metadata !DIExpression()), !dbg [[DBG292:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META290:![0-9]+]], metadata !DIExpression()), !dbg [[DBG291:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG293:![0-9]+]] -// SIMD4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG295:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG296:![0-9]+]] +// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG292:![0-9]+]] +// SIMD4-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG294:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG295:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S4C2Ei -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG297:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG296:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META298:![0-9]+]], metadata !DIExpression()), !dbg [[DBG299:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META297:![0-9]+]], metadata !DIExpression()), !dbg [[DBG298:![0-9]+]] // SIMD4-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META300:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META299:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG302:![0-9]+]] -// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG303:![0-9]+]] -// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG302]] -// SIMD4-NEXT: ret void, !dbg [[DBG304:![0-9]+]] +// SIMD4-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG301:![0-9]+]] +// SIMD4-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG302:![0-9]+]] +// SIMD4-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG301]] +// SIMD4-NEXT: ret void, !dbg [[DBG303:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_ZN2S4D2Ev -// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG305:![0-9]+]] { +// SIMD4-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG304:![0-9]+]] { // SIMD4-NEXT: entry: // SIMD4-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // SIMD4-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META306:![0-9]+]], metadata !DIExpression()), !dbg [[DBG307:![0-9]+]] +// SIMD4-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META305:![0-9]+]], metadata !DIExpression()), !dbg [[DBG306:![0-9]+]] // SIMD4-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG308:![0-9]+]] -// SIMD4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG310:![0-9]+]] -// SIMD4-NEXT: ret void, !dbg [[DBG311:![0-9]+]] +// SIMD4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG307:![0-9]+]] +// SIMD4-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG309:![0-9]+]] +// SIMD4-NEXT: ret void, !dbg [[DBG310:![0-9]+]] // // // SIMD4-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// SIMD4-SAME: () #[[ATTR0]] !dbg [[DBG312:![0-9]+]] { +// SIMD4-SAME: () #[[ATTR0]] !dbg [[DBG311:![0-9]+]] { // SIMD4-NEXT: entry: -// SIMD4-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG314:![0-9]+]] -// SIMD4-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG314]] -// SIMD4-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG314]] +// SIMD4-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG313:![0-9]+]] +// SIMD4-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG313]] +// SIMD4-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG313]] // SIMD4-NEXT: ret void // // @@ -6440,7 +6440,7 @@ int foobar() { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META118:![0-9]+]], metadata !DIExpression()), !dbg [[DBG120:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META118:![0-9]+]], metadata !DIExpression()), !dbg [[DBG120:![0-9]+]] // DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG121:![0-9]+]] // DEBUG1-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 5), !dbg [[DBG122:![0-9]+]] // DEBUG1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG121]] @@ -6453,9 +6453,9 @@ int foobar() { // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META124:![0-9]+]], metadata !DIExpression()), !dbg [[DBG126:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META124:![0-9]+]], metadata !DIExpression()), !dbg [[DBG126:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG129:![0-9]+]] // DEBUG1-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG129]] @@ -6467,7 +6467,7 @@ int foobar() { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] // DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG133]] // DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR4:[0-9]+]], !dbg [[DBG133]] // DEBUG1-NEXT: ret void, !dbg [[DBG134:![0-9]+]] @@ -6478,7 +6478,7 @@ int foobar() { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META136:![0-9]+]], metadata !DIExpression()), !dbg [[DBG137:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META136:![0-9]+]], metadata !DIExpression()), !dbg [[DBG137:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 // DEBUG1-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]], !dbg [[DBG138:![0-9]+]] // DEBUG1-NEXT: ret void, !dbg [[DBG139:![0-9]+]] @@ -6502,47 +6502,47 @@ int foobar() { // DEBUG1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT9:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META143:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META143:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] // DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG145:![0-9]+]] // DEBUG1-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG146:![0-9]+]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146]] // DEBUG1-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG147:![0-9]+]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) -// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG148:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG148:![0-9]+]] // DEBUG1: invoke.cont: // DEBUG1-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1, !dbg [[DBG147]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// DEBUG1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG149:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG149:![0-9]+]] // DEBUG1: invoke.cont3: // DEBUG1-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1, !dbg [[DBG147]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG147]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// DEBUG1-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]], !dbg [[DBG150:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]], !dbg [[DBG150:![0-9]+]] // DEBUG1: invoke.cont5: // DEBUG1-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1, !dbg [[DBG146]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG146]] // DEBUG1-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0, !dbg [[DBG151:![0-9]+]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// DEBUG1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]], !dbg [[DBG152:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]], !dbg [[DBG152:![0-9]+]] // DEBUG1: invoke.cont11: // DEBUG1-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1, !dbg [[DBG151]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// DEBUG1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]], !dbg [[DBG153:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]], !dbg [[DBG153:![0-9]+]] // DEBUG1: invoke.cont13: // DEBUG1-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1, !dbg [[DBG151]] // DEBUG1-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG151]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// DEBUG1-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]], !dbg [[DBG154:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]], !dbg [[DBG154:![0-9]+]] // DEBUG1: invoke.cont15: // DEBUG1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG145]] // DEBUG1-NEXT: ret ptr [[TMP2]], !dbg [[DBG145]] // DEBUG1: lpad: // DEBUG1-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 } -// DEBUG1-NEXT: cleanup, !dbg [[DBG144]] +// DEBUG1-NEXT: cleanup, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0, !dbg [[DBG144]] // DEBUG1-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1, !dbg [[DBG144]] @@ -6560,7 +6560,7 @@ int foobar() { // DEBUG1-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG147]] // DEBUG1: lpad10: // DEBUG1-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// DEBUG1-NEXT: cleanup, !dbg [[DBG144]] +// DEBUG1-NEXT: cleanup, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0, !dbg [[DBG144]] // DEBUG1-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG144]] // DEBUG1-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1, !dbg [[DBG144]] @@ -6603,7 +6603,7 @@ int foobar() { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META156:![0-9]+]], metadata !DIExpression()), !dbg [[DBG157:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META156:![0-9]+]], metadata !DIExpression()), !dbg [[DBG157:![0-9]+]] // DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG157]] // DEBUG1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 6, !dbg [[DBG157]] // DEBUG1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG157]] @@ -6628,209 +6628,209 @@ int foobar() { // DEBUG1-LABEL: define {{[^@]+}}@__cxx_global_var_init // DEBUG1-SAME: () #[[ATTR0]] !dbg [[DBG161:![0-9]+]] { // DEBUG1-NEXT: entry: -// DEBUG1-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG165:![0-9]+]] -// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG167:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG168:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG164:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG166:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG167:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S1C2Ei -// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG169:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG168:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META170:![0-9]+]], metadata !DIExpression()), !dbg [[DBG171:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META169:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG173:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG172:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG174:![0-9]+]] -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG175:![0-9]+]] -// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG174]] -// DEBUG1-NEXT: ret void, !dbg [[DBG176:![0-9]+]] +// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG173:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG174:![0-9]+]] +// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG173]] +// DEBUG1-NEXT: ret void, !dbg [[DBG175:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S1D2Ev -// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG177:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG176:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META178:![0-9]+]], metadata !DIExpression()), !dbg [[DBG179:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META177:![0-9]+]], metadata !DIExpression()), !dbg [[DBG178:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG180:![0-9]+]] -// DEBUG1-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG182:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG183:![0-9]+]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG179:![0-9]+]] +// DEBUG1-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG181:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG182:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@__cxx_global_var_init.4 -// DEBUG1-SAME: () #[[ATTR0]] !dbg [[DBG184:![0-9]+]] { +// DEBUG1-SAME: () #[[ATTR0]] !dbg [[DBG183:![0-9]+]] { // DEBUG1-NEXT: entry: -// DEBUG1-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG185:![0-9]+]] -// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG187:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG188:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG184:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG186:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG187:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S2C1Ei -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG189:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG188:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META190:![0-9]+]], metadata !DIExpression()), !dbg [[DBG192:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META189:![0-9]+]], metadata !DIExpression()), !dbg [[DBG191:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META193:![0-9]+]], metadata !DIExpression()), !dbg [[DBG194:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META192:![0-9]+]], metadata !DIExpression()), !dbg [[DBG193:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG195:![0-9]+]] -// DEBUG1-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG195]] -// DEBUG1-NEXT: ret void, !dbg [[DBG196:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG194:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG194]] +// DEBUG1-NEXT: ret void, !dbg [[DBG195:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S2D1Ev -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG197:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG196:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META198:![0-9]+]], metadata !DIExpression()), !dbg [[DBG199:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META197:![0-9]+]], metadata !DIExpression()), !dbg [[DBG198:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR4]], !dbg [[DBG200:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG201:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR4]], !dbg [[DBG199:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG200:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S2C2Ei -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG202:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG201:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META203:![0-9]+]], metadata !DIExpression()), !dbg [[DBG204:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META202:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META205:![0-9]+]], metadata !DIExpression()), !dbg [[DBG206:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG205:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG207:![0-9]+]] -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG208:![0-9]+]] -// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG207]] -// DEBUG1-NEXT: ret void, !dbg [[DBG209:![0-9]+]] +// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG206:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG207:![0-9]+]] +// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG206]] +// DEBUG1-NEXT: ret void, !dbg [[DBG208:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S2D2Ev -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG210:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG209:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META211:![0-9]+]], metadata !DIExpression()), !dbg [[DBG212:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META210:![0-9]+]], metadata !DIExpression()), !dbg [[DBG211:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG213:![0-9]+]] -// DEBUG1-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG215:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG216:![0-9]+]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG212:![0-9]+]] +// DEBUG1-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG214:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG215:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@__cxx_global_var_init.5 -// DEBUG1-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG217:![0-9]+]] { +// DEBUG1-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG216:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: [[ARRAYINIT_ENDOFINIT5:%.*]] = alloca ptr, align 8 -// DEBUG1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG218:![0-9]+]] -// DEBUG1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG220:![0-9]+]] +// DEBUG1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG217:![0-9]+]] +// DEBUG1-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG219:![0-9]+]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG221:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG220:![0-9]+]] // DEBUG1: invoke.cont: -// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG220]] +// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG219]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// DEBUG1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG222:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG221:![0-9]+]] // DEBUG1: invoke.cont2: -// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG220]] +// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG219]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// DEBUG1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG223:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG222:![0-9]+]] // DEBUG1: invoke.cont3: -// DEBUG1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG218]] -// DEBUG1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG224:![0-9]+]] +// DEBUG1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG217]] +// DEBUG1-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG223:![0-9]+]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// DEBUG1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG225:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG224:![0-9]+]] // DEBUG1: invoke.cont7: -// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG224]] +// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG223]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// DEBUG1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG226:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG225:![0-9]+]] // DEBUG1: invoke.cont8: -// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG224]] +// DEBUG1-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG223]] // DEBUG1-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// DEBUG1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG227:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG226:![0-9]+]] // DEBUG1: invoke.cont9: -// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG228:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG228]] +// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG227:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG227]] // DEBUG1: lpad: // DEBUG1-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } -// DEBUG1-NEXT: cleanup, !dbg [[DBG229:![0-9]+]] -// DEBUG1-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG229]] -// DEBUG1-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG229]] -// DEBUG1-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG229]] -// DEBUG1-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG229]] -// DEBUG1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG220]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG220]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG220]] +// DEBUG1-NEXT: cleanup, !dbg [[DBG228:![0-9]+]] +// DEBUG1-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0, !dbg [[DBG228]] +// DEBUG1-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG228]] +// DEBUG1-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1, !dbg [[DBG228]] +// DEBUG1-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG228]] +// DEBUG1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG219]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP4]], !dbg [[DBG219]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG219]] // DEBUG1: arraydestroy.body: -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG220]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG220]] -// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG220]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG220]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG220]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP4]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG219]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG219]] +// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG219]] +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG219]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG219]] // DEBUG1: arraydestroy.done4: -// DEBUG1-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG220]] +// DEBUG1-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG219]] // DEBUG1: lpad6: // DEBUG1-NEXT: [[TMP5:%.*]] = landingpad { ptr, i32 } -// DEBUG1-NEXT: cleanup, !dbg [[DBG229]] -// DEBUG1-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG229]] -// DEBUG1-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG229]] -// DEBUG1-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG229]] -// DEBUG1-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG229]] -// DEBUG1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG224]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG224]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG224]] +// DEBUG1-NEXT: cleanup, !dbg [[DBG228]] +// DEBUG1-NEXT: [[TMP6:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 0, !dbg [[DBG228]] +// DEBUG1-NEXT: store ptr [[TMP6]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG228]] +// DEBUG1-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP5]], 1, !dbg [[DBG228]] +// DEBUG1-NEXT: store i32 [[TMP7]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG228]] +// DEBUG1-NEXT: [[TMP8:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG223]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP8]], !dbg [[DBG223]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG223]] // DEBUG1: arraydestroy.body11: -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG224]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG224]] -// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR4]], !dbg [[DBG224]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG224]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG224]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP8]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG223]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG223]] +// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR4]], !dbg [[DBG223]] +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG223]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG223]] // DEBUG1: arraydestroy.done15: -// DEBUG1-NEXT: br label [[EHCLEANUP]], !dbg [[DBG224]] +// DEBUG1-NEXT: br label [[EHCLEANUP]], !dbg [[DBG223]] // DEBUG1: ehcleanup: -// DEBUG1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG218]] -// DEBUG1-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG218]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG218]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG218]] +// DEBUG1-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG217]] +// DEBUG1-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP9]], i64 0, i64 0, !dbg [[DBG217]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG217]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG217]] // DEBUG1: arraydestroy.body17: -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG218]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG218]] -// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG218]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG218]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG218]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG217]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG217]] +// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG217]] +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG217]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG217]] // DEBUG1: arraydestroy.done21: -// DEBUG1-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG218]] +// DEBUG1-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG217]] // DEBUG1: eh.resume: -// DEBUG1-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG218]] -// DEBUG1-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG218]] -// DEBUG1-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG218]] -// DEBUG1-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG218]] -// DEBUG1-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG218]] +// DEBUG1-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG217]] +// DEBUG1-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG217]] +// DEBUG1-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG217]] +// DEBUG1-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG217]] +// DEBUG1-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG217]] // // // DEBUG1-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG230:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG229:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META233:![0-9]+]], metadata !DIExpression()), !dbg [[DBG234:![0-9]+]] -// DEBUG1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG234]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META232:![0-9]+]], metadata !DIExpression()), !dbg [[DBG233:![0-9]+]] +// DEBUG1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG233]] // DEBUG1: arraydestroy.body: -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG234]] -// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG234]] -// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG234]] -// DEBUG1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG234]] -// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG234]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG233]] +// DEBUG1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG233]] +// DEBUG1-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG233]] +// DEBUG1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG233]] +// DEBUG1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG233]] // DEBUG1: arraydestroy.done1: -// DEBUG1-NEXT: ret void, !dbg [[DBG234]] +// DEBUG1-NEXT: ret void, !dbg [[DBG233]] // // // DEBUG1-LABEL: define {{[^@]+}}@main @@ -6840,9 +6840,9 @@ int foobar() { // DEBUG1-NEXT: [[RES:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB9:[0-9]+]]) +// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB9:[0-9]+]]), !dbg [[DBG234:![0-9]+]] // DEBUG1-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META235:![0-9]+]], metadata !DIExpression()), !dbg [[DBG236:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META235:![0-9]+]], metadata !DIExpression()), !dbg [[DBG236:![0-9]+]] // DEBUG1-NEXT: [[TMP1:%.*]] = load atomic i8, ptr @_ZGVZ4mainE2sm acquire, align 8, !dbg [[DBG237:![0-9]+]] // DEBUG1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP1]], 0, !dbg [[DBG237]] // DEBUG1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG237]], !prof [[PROF238:![0-9]+]] @@ -6853,76 +6853,76 @@ int foobar() { // DEBUG1: init: // DEBUG1-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB7:[0-9]+]]), !dbg [[DBG237]] // DEBUG1-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB7]], ptr @_ZZ4mainE2sm, ptr @.__kmpc_global_ctor_..6, ptr null, ptr @.__kmpc_global_dtor_..7), !dbg [[DBG237]] -// DEBUG1-NEXT: [[TMP4:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB9]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG239:![0-9]+]] -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP4]], i32 0, i32 0, !dbg [[DBG240:![0-9]+]] -// DEBUG1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG240]] +// DEBUG1-NEXT: [[TMP4:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB9]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG234]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP4]], i32 0, i32 0, !dbg [[DBG239:![0-9]+]] +// DEBUG1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG239]] // DEBUG1-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP5]]) -// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG241:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG240:![0-9]+]] // DEBUG1: invoke.cont: // DEBUG1-NEXT: [[TMP6:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG237]] // DEBUG1-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR4]], !dbg [[DBG237]] // DEBUG1-NEXT: br label [[INIT_END]], !dbg [[DBG237]] // DEBUG1: init.end: -// DEBUG1-NEXT: [[TMP7:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB11:[0-9]+]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG242:![0-9]+]] -// DEBUG1-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP7]], i32 0, i32 0, !dbg [[DBG243:![0-9]+]] -// DEBUG1-NEXT: [[TMP8:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG243]] -// DEBUG1-NEXT: store i32 [[TMP8]], ptr [[RES]], align 4, !dbg [[DBG244:![0-9]+]] -// DEBUG1-NEXT: [[TMP9:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB13:[0-9]+]], i32 [[TMP0]], ptr @_ZZ4mainE2sm, i64 24, ptr @_ZZ4mainE2sm.cache.), !dbg [[DBG245:![0-9]+]] -// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[TMP9]], i32 0, i32 0, !dbg [[DBG246:![0-9]+]] -// DEBUG1-NEXT: [[TMP10:%.*]] = load i32, ptr [[A2]], align 8, !dbg [[DBG246]] -// DEBUG1-NEXT: [[TMP11:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG247:![0-9]+]] -// DEBUG1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP10]], !dbg [[DBG247]] -// DEBUG1-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG247]] -// DEBUG1-NEXT: [[TMP12:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB15:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG248:![0-9]+]] -// DEBUG1-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP12]], i32 0, i32 0, !dbg [[DBG249:![0-9]+]] -// DEBUG1-NEXT: [[TMP13:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG249]] -// DEBUG1-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG250:![0-9]+]] -// DEBUG1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG250]] -// DEBUG1-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG250]] -// DEBUG1-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG251:![0-9]+]] -// DEBUG1-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG252:![0-9]+]] -// DEBUG1-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG252]] -// DEBUG1-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG252]] -// DEBUG1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB17:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG253:![0-9]+]] -// DEBUG1-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP17]], i32 0, i32 0, !dbg [[DBG254:![0-9]+]] -// DEBUG1-NEXT: [[TMP18:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG254]] -// DEBUG1-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG255:![0-9]+]] -// DEBUG1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP19]], [[TMP18]], !dbg [[DBG255]] -// DEBUG1-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG255]] -// DEBUG1-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB19:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG256:![0-9]+]] -// DEBUG1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP20]], i64 0, i64 1, !dbg [[DBG256]] -// DEBUG1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG256]] -// DEBUG1-NEXT: [[A9:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX8]], i32 0, i32 0, !dbg [[DBG257:![0-9]+]] -// DEBUG1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A9]], align 4, !dbg [[DBG257]] -// DEBUG1-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG258:![0-9]+]] -// DEBUG1-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG258]] -// DEBUG1-NEXT: store i32 [[ADD10]], ptr [[RES]], align 4, !dbg [[DBG258]] -// DEBUG1-NEXT: [[TMP23:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB21:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG259:![0-9]+]] -// DEBUG1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4, !dbg [[DBG259]] -// DEBUG1-NEXT: [[TMP25:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG260:![0-9]+]] -// DEBUG1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP25]], [[TMP24]], !dbg [[DBG260]] -// DEBUG1-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG260]] -// DEBUG1-NEXT: [[TMP26:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB23:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG261:![0-9]+]] -// DEBUG1-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP26]], align 4, !dbg [[DBG261]] -// DEBUG1-NEXT: [[CONV:%.*]] = fptosi float [[TMP27]] to i32, !dbg [[DBG261]] -// DEBUG1-NEXT: [[TMP28:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG262:![0-9]+]] -// DEBUG1-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP28]], [[CONV]], !dbg [[DBG262]] -// DEBUG1-NEXT: store i32 [[ADD12]], ptr [[RES]], align 4, !dbg [[DBG262]] -// DEBUG1-NEXT: [[TMP29:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB25:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG263:![0-9]+]] -// DEBUG1-NEXT: [[A13:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP29]], i32 0, i32 0, !dbg [[DBG264:![0-9]+]] -// DEBUG1-NEXT: [[TMP30:%.*]] = load i32, ptr [[A13]], align 4, !dbg [[DBG264]] -// DEBUG1-NEXT: [[TMP31:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG265:![0-9]+]] -// DEBUG1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP31]], [[TMP30]], !dbg [[DBG265]] -// DEBUG1-NEXT: store i32 [[ADD14]], ptr [[RES]], align 4, !dbg [[DBG265]] -// DEBUG1-NEXT: [[TMP32:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG266:![0-9]+]] -// DEBUG1-NEXT: ret i32 [[TMP32]], !dbg [[DBG267:![0-9]+]] +// DEBUG1-NEXT: [[TMP7:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB11:[0-9]+]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG241:![0-9]+]] +// DEBUG1-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP7]], i32 0, i32 0, !dbg [[DBG242:![0-9]+]] +// DEBUG1-NEXT: [[TMP8:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG242]] +// DEBUG1-NEXT: store i32 [[TMP8]], ptr [[RES]], align 4, !dbg [[DBG243:![0-9]+]] +// DEBUG1-NEXT: [[TMP9:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB13:[0-9]+]], i32 [[TMP0]], ptr @_ZZ4mainE2sm, i64 24, ptr @_ZZ4mainE2sm.cache.), !dbg [[DBG244:![0-9]+]] +// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[TMP9]], i32 0, i32 0, !dbg [[DBG245:![0-9]+]] +// DEBUG1-NEXT: [[TMP10:%.*]] = load i32, ptr [[A2]], align 8, !dbg [[DBG245]] +// DEBUG1-NEXT: [[TMP11:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG246:![0-9]+]] +// DEBUG1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP10]], !dbg [[DBG246]] +// DEBUG1-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG246]] +// DEBUG1-NEXT: [[TMP12:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB15:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG247:![0-9]+]] +// DEBUG1-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP12]], i32 0, i32 0, !dbg [[DBG248:![0-9]+]] +// DEBUG1-NEXT: [[TMP13:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG248]] +// DEBUG1-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG249:![0-9]+]] +// DEBUG1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG249]] +// DEBUG1-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG249]] +// DEBUG1-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG250:![0-9]+]] +// DEBUG1-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG251:![0-9]+]] +// DEBUG1-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG251]] +// DEBUG1-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG251]] +// DEBUG1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB17:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG252:![0-9]+]] +// DEBUG1-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP17]], i32 0, i32 0, !dbg [[DBG253:![0-9]+]] +// DEBUG1-NEXT: [[TMP18:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG253]] +// DEBUG1-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG254:![0-9]+]] +// DEBUG1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP19]], [[TMP18]], !dbg [[DBG254]] +// DEBUG1-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG254]] +// DEBUG1-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB19:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG255:![0-9]+]] +// DEBUG1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP20]], i64 0, i64 1, !dbg [[DBG255]] +// DEBUG1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG255]] +// DEBUG1-NEXT: [[A9:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX8]], i32 0, i32 0, !dbg [[DBG256:![0-9]+]] +// DEBUG1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A9]], align 4, !dbg [[DBG256]] +// DEBUG1-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG257:![0-9]+]] +// DEBUG1-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG257]] +// DEBUG1-NEXT: store i32 [[ADD10]], ptr [[RES]], align 4, !dbg [[DBG257]] +// DEBUG1-NEXT: [[TMP23:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB21:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG258:![0-9]+]] +// DEBUG1-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4, !dbg [[DBG258]] +// DEBUG1-NEXT: [[TMP25:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG259:![0-9]+]] +// DEBUG1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP25]], [[TMP24]], !dbg [[DBG259]] +// DEBUG1-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG259]] +// DEBUG1-NEXT: [[TMP26:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB23:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG260:![0-9]+]] +// DEBUG1-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP26]], align 4, !dbg [[DBG260]] +// DEBUG1-NEXT: [[CONV:%.*]] = fptosi float [[TMP27]] to i32, !dbg [[DBG260]] +// DEBUG1-NEXT: [[TMP28:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG261:![0-9]+]] +// DEBUG1-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP28]], [[CONV]], !dbg [[DBG261]] +// DEBUG1-NEXT: store i32 [[ADD12]], ptr [[RES]], align 4, !dbg [[DBG261]] +// DEBUG1-NEXT: [[TMP29:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB25:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG262:![0-9]+]] +// DEBUG1-NEXT: [[A13:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP29]], i32 0, i32 0, !dbg [[DBG263:![0-9]+]] +// DEBUG1-NEXT: [[TMP30:%.*]] = load i32, ptr [[A13]], align 4, !dbg [[DBG263]] +// DEBUG1-NEXT: [[TMP31:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG264:![0-9]+]] +// DEBUG1-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP31]], [[TMP30]], !dbg [[DBG264]] +// DEBUG1-NEXT: store i32 [[ADD14]], ptr [[RES]], align 4, !dbg [[DBG264]] +// DEBUG1-NEXT: [[TMP32:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG265:![0-9]+]] +// DEBUG1-NEXT: ret i32 [[TMP32]], !dbg [[DBG266:![0-9]+]] // DEBUG1: lpad: // DEBUG1-NEXT: [[TMP33:%.*]] = landingpad { ptr, i32 } -// DEBUG1-NEXT: cleanup, !dbg [[DBG268:![0-9]+]] -// DEBUG1-NEXT: [[TMP34:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 0, !dbg [[DBG268]] -// DEBUG1-NEXT: store ptr [[TMP34]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG268]] -// DEBUG1-NEXT: [[TMP35:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 1, !dbg [[DBG268]] -// DEBUG1-NEXT: store i32 [[TMP35]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG268]] +// DEBUG1-NEXT: cleanup, !dbg [[DBG267:![0-9]+]] +// DEBUG1-NEXT: [[TMP34:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 0, !dbg [[DBG267]] +// DEBUG1-NEXT: store ptr [[TMP34]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG267]] +// DEBUG1-NEXT: [[TMP35:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 1, !dbg [[DBG267]] +// DEBUG1-NEXT: store i32 [[TMP35]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG267]] // DEBUG1-NEXT: call void @__cxa_guard_abort(ptr @_ZGVZ4mainE2sm) #[[ATTR4]], !dbg [[DBG237]] // DEBUG1-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG237]] // DEBUG1: eh.resume: @@ -6934,436 +6934,436 @@ int foobar() { // // // DEBUG1-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_..6 -// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG269:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG268:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 -// DEBUG1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB5:[0-9]+]]) +// DEBUG1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB5:[0-9]+]]), !dbg [[DBG269:![0-9]+]] // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META270:![0-9]+]], metadata !DIExpression()), !dbg [[DBG271:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META270:![0-9]+]], metadata !DIExpression()), !dbg [[DBG271:![0-9]+]] // DEBUG1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG272:![0-9]+]] -// DEBUG1-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB5]], i32 [[TMP1]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG273:![0-9]+]] -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG274:![0-9]+]] -// DEBUG1-NEXT: [[TMP4:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG274]] -// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) [[TMP2]], i32 noundef [[TMP4]]), !dbg [[DBG275:![0-9]+]] +// DEBUG1-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB5]], i32 [[TMP1]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG269]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG273:![0-9]+]] +// DEBUG1-NEXT: [[TMP4:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG273]] +// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) [[TMP2]], i32 noundef [[TMP4]]), !dbg [[DBG274:![0-9]+]] // DEBUG1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG272]] // DEBUG1-NEXT: ret ptr [[TMP5]], !dbg [[DBG272]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC1Ei -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG276:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG275:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META277:![0-9]+]], metadata !DIExpression()), !dbg [[DBG279:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META276:![0-9]+]], metadata !DIExpression()), !dbg [[DBG278:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META280:![0-9]+]], metadata !DIExpression()), !dbg [[DBG281:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META279:![0-9]+]], metadata !DIExpression()), !dbg [[DBG280:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG282:![0-9]+]] -// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG282]] -// DEBUG1-NEXT: ret void, !dbg [[DBG283:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG281:![0-9]+]] +// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG281]] +// DEBUG1-NEXT: ret void, !dbg [[DBG282:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..7 -// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG284:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG283:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META285:![0-9]+]], metadata !DIExpression()), !dbg [[DBG286:![0-9]+]] -// DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG286]] -// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainD1Ev(ptr noundef nonnull align 8 dereferenceable(24) [[TMP1]]) #[[ATTR4]], !dbg [[DBG286]] -// DEBUG1-NEXT: ret void, !dbg [[DBG287:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META284:![0-9]+]], metadata !DIExpression()), !dbg [[DBG285:![0-9]+]] +// DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG285]] +// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainD1Ev(ptr noundef nonnull align 8 dereferenceable(24) [[TMP1]]) #[[ATTR4]], !dbg [[DBG285]] +// DEBUG1-NEXT: ret void, !dbg [[DBG286:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD1Ev -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG288:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG287:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META289:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META288:![0-9]+]], metadata !DIExpression()), !dbg [[DBG289:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR4]], !dbg [[DBG291:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG292:![0-9]+]] +// DEBUG1-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR4]], !dbg [[DBG290:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG291:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC2Ei -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG293:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG292:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META294:![0-9]+]], metadata !DIExpression()), !dbg [[DBG295:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META293:![0-9]+]], metadata !DIExpression()), !dbg [[DBG294:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META296:![0-9]+]], metadata !DIExpression()), !dbg [[DBG297:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META295:![0-9]+]], metadata !DIExpression()), !dbg [[DBG296:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG298:![0-9]+]] -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG299:![0-9]+]] -// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG298]] -// DEBUG1-NEXT: ret void, !dbg [[DBG300:![0-9]+]] +// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG297:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG298:![0-9]+]] +// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG297]] +// DEBUG1-NEXT: ret void, !dbg [[DBG299:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD2Ev -// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG301:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG300:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META302:![0-9]+]], metadata !DIExpression()), !dbg [[DBG303:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META301:![0-9]+]], metadata !DIExpression()), !dbg [[DBG302:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG304:![0-9]+]] -// DEBUG1-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG306:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG307:![0-9]+]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG303:![0-9]+]] +// DEBUG1-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG305:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG306:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_Z6foobarv -// DEBUG1-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG308:![0-9]+]] { +// DEBUG1-SAME: () #[[ATTR3]] !dbg [[DBG307:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[RES:%.*]] = alloca i32, align 4 -// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB27:[0-9]+]]) -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META309:![0-9]+]], metadata !DIExpression()), !dbg [[DBG310:![0-9]+]] -// DEBUG1-NEXT: [[TMP1:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB27]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG311:![0-9]+]] -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP1]], i32 0, i32 0, !dbg [[DBG312:![0-9]+]] -// DEBUG1-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG312]] -// DEBUG1-NEXT: store i32 [[TMP2]], ptr [[RES]], align 4, !dbg [[DBG313:![0-9]+]] -// DEBUG1-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB29:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG314:![0-9]+]] -// DEBUG1-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG315:![0-9]+]] -// DEBUG1-NEXT: [[TMP4:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG315]] -// DEBUG1-NEXT: [[TMP5:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG316:![0-9]+]] -// DEBUG1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP4]], !dbg [[DBG316]] -// DEBUG1-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG316]] -// DEBUG1-NEXT: [[TMP6:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG317:![0-9]+]] -// DEBUG1-NEXT: [[TMP7:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG318:![0-9]+]] -// DEBUG1-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP7]], [[TMP6]], !dbg [[DBG318]] -// DEBUG1-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG318]] -// DEBUG1-NEXT: [[TMP8:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB31:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG319:![0-9]+]] -// DEBUG1-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP8]], i32 0, i32 0, !dbg [[DBG320:![0-9]+]] -// DEBUG1-NEXT: [[TMP9:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG320]] -// DEBUG1-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG321:![0-9]+]] -// DEBUG1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG321]] -// DEBUG1-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG321]] -// DEBUG1-NEXT: [[TMP11:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB33:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG322:![0-9]+]] -// DEBUG1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP11]], i64 0, i64 1, !dbg [[DBG322]] -// DEBUG1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG322]] -// DEBUG1-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX5]], i32 0, i32 0, !dbg [[DBG323:![0-9]+]] -// DEBUG1-NEXT: [[TMP12:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG323]] -// DEBUG1-NEXT: [[TMP13:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG324:![0-9]+]] -// DEBUG1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP13]], [[TMP12]], !dbg [[DBG324]] -// DEBUG1-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG324]] -// DEBUG1-NEXT: [[TMP14:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB35:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG325:![0-9]+]] -// DEBUG1-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4, !dbg [[DBG325]] -// DEBUG1-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG326:![0-9]+]] -// DEBUG1-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG326]] -// DEBUG1-NEXT: store i32 [[ADD8]], ptr [[RES]], align 4, !dbg [[DBG326]] -// DEBUG1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB37:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG327:![0-9]+]] -// DEBUG1-NEXT: [[TMP18:%.*]] = load float, ptr [[TMP17]], align 4, !dbg [[DBG327]] -// DEBUG1-NEXT: [[CONV:%.*]] = fptosi float [[TMP18]] to i32, !dbg [[DBG327]] -// DEBUG1-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG328:![0-9]+]] -// DEBUG1-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP19]], [[CONV]], !dbg [[DBG328]] -// DEBUG1-NEXT: store i32 [[ADD9]], ptr [[RES]], align 4, !dbg [[DBG328]] -// DEBUG1-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB39:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG329:![0-9]+]] -// DEBUG1-NEXT: [[A10:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP20]], i32 0, i32 0, !dbg [[DBG330:![0-9]+]] -// DEBUG1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A10]], align 4, !dbg [[DBG330]] -// DEBUG1-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG331:![0-9]+]] -// DEBUG1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG331]] -// DEBUG1-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG331]] -// DEBUG1-NEXT: [[TMP23:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG332:![0-9]+]] -// DEBUG1-NEXT: ret i32 [[TMP23]], !dbg [[DBG333:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB27:[0-9]+]]), !dbg [[DBG308:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META309:![0-9]+]], metadata !DIExpression()), !dbg [[DBG310:![0-9]+]] +// DEBUG1-NEXT: [[TMP1:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB27]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG308]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP1]], i32 0, i32 0, !dbg [[DBG311:![0-9]+]] +// DEBUG1-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG311]] +// DEBUG1-NEXT: store i32 [[TMP2]], ptr [[RES]], align 4, !dbg [[DBG312:![0-9]+]] +// DEBUG1-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB29:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG313:![0-9]+]] +// DEBUG1-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG314:![0-9]+]] +// DEBUG1-NEXT: [[TMP4:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG314]] +// DEBUG1-NEXT: [[TMP5:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG315:![0-9]+]] +// DEBUG1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP4]], !dbg [[DBG315]] +// DEBUG1-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG315]] +// DEBUG1-NEXT: [[TMP6:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG316:![0-9]+]] +// DEBUG1-NEXT: [[TMP7:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG317:![0-9]+]] +// DEBUG1-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP7]], [[TMP6]], !dbg [[DBG317]] +// DEBUG1-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG317]] +// DEBUG1-NEXT: [[TMP8:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB31:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG318:![0-9]+]] +// DEBUG1-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP8]], i32 0, i32 0, !dbg [[DBG319:![0-9]+]] +// DEBUG1-NEXT: [[TMP9:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG319]] +// DEBUG1-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG320:![0-9]+]] +// DEBUG1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG320]] +// DEBUG1-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG320]] +// DEBUG1-NEXT: [[TMP11:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB33:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG321:![0-9]+]] +// DEBUG1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP11]], i64 0, i64 1, !dbg [[DBG321]] +// DEBUG1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG321]] +// DEBUG1-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX5]], i32 0, i32 0, !dbg [[DBG322:![0-9]+]] +// DEBUG1-NEXT: [[TMP12:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG322]] +// DEBUG1-NEXT: [[TMP13:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG323:![0-9]+]] +// DEBUG1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP13]], [[TMP12]], !dbg [[DBG323]] +// DEBUG1-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG323]] +// DEBUG1-NEXT: [[TMP14:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB35:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG324:![0-9]+]] +// DEBUG1-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4, !dbg [[DBG324]] +// DEBUG1-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG325:![0-9]+]] +// DEBUG1-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG325]] +// DEBUG1-NEXT: store i32 [[ADD8]], ptr [[RES]], align 4, !dbg [[DBG325]] +// DEBUG1-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB37:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG326:![0-9]+]] +// DEBUG1-NEXT: [[TMP18:%.*]] = load float, ptr [[TMP17]], align 4, !dbg [[DBG326]] +// DEBUG1-NEXT: [[CONV:%.*]] = fptosi float [[TMP18]] to i32, !dbg [[DBG326]] +// DEBUG1-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG327:![0-9]+]] +// DEBUG1-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP19]], [[CONV]], !dbg [[DBG327]] +// DEBUG1-NEXT: store i32 [[ADD9]], ptr [[RES]], align 4, !dbg [[DBG327]] +// DEBUG1-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB39:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG328:![0-9]+]] +// DEBUG1-NEXT: [[A10:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP20]], i32 0, i32 0, !dbg [[DBG329:![0-9]+]] +// DEBUG1-NEXT: [[TMP21:%.*]] = load i32, ptr [[A10]], align 4, !dbg [[DBG329]] +// DEBUG1-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG330:![0-9]+]] +// DEBUG1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG330]] +// DEBUG1-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG330]] +// DEBUG1-NEXT: [[TMP23:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG331:![0-9]+]] +// DEBUG1-NEXT: ret i32 [[TMP23]], !dbg [[DBG332:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@__cxx_global_var_init.8 -// DEBUG1-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG334:![0-9]+]] { +// DEBUG1-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG333:![0-9]+]] { // DEBUG1-NEXT: entry: -// DEBUG1-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG335:![0-9]+]] -// DEBUG1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG335]] -// DEBUG1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG335]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG334:![0-9]+]] +// DEBUG1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG334]] +// DEBUG1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG334]] // DEBUG1: init.check: -// DEBUG1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG335]] -// DEBUG1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB41:[0-9]+]]), !dbg [[DBG335]] -// DEBUG1-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB41]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..9, ptr null, ptr @.__kmpc_global_dtor_..10), !dbg [[DBG335]] -// DEBUG1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG336:![0-9]+]] -// DEBUG1-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG335]] -// DEBUG1-NEXT: br label [[INIT_END]], !dbg [[DBG335]] +// DEBUG1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG334]] +// DEBUG1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB41:[0-9]+]]), !dbg [[DBG334]] +// DEBUG1-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB41]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..9, ptr null, ptr @.__kmpc_global_dtor_..10), !dbg [[DBG334]] +// DEBUG1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG335:![0-9]+]] +// DEBUG1-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG334]] +// DEBUG1-NEXT: br label [[INIT_END]], !dbg [[DBG334]] // DEBUG1: init.end: -// DEBUG1-NEXT: ret void, !dbg [[DBG338:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG337:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_..9 -// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG339:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG338:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META340:![0-9]+]], metadata !DIExpression()), !dbg [[DBG341:![0-9]+]] -// DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG342:![0-9]+]] -// DEBUG1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]], i32 noundef 23), !dbg [[DBG343:![0-9]+]] -// DEBUG1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG342]] -// DEBUG1-NEXT: ret ptr [[TMP2]], !dbg [[DBG342]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META339:![0-9]+]], metadata !DIExpression()), !dbg [[DBG340:![0-9]+]] +// DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG341:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]], i32 noundef 23), !dbg [[DBG342:![0-9]+]] +// DEBUG1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG341]] +// DEBUG1-NEXT: ret ptr [[TMP2]], !dbg [[DBG341]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S4C1Ei -// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG344:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG343:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META345:![0-9]+]], metadata !DIExpression()), !dbg [[DBG347:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META344:![0-9]+]], metadata !DIExpression()), !dbg [[DBG346:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META348:![0-9]+]], metadata !DIExpression()), !dbg [[DBG349:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META347:![0-9]+]], metadata !DIExpression()), !dbg [[DBG348:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG350:![0-9]+]] -// DEBUG1-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG350]] -// DEBUG1-NEXT: ret void, !dbg [[DBG351:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG349:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG349]] +// DEBUG1-NEXT: ret void, !dbg [[DBG350:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..10 -// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG352:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG351:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META353:![0-9]+]], metadata !DIExpression()), !dbg [[DBG354:![0-9]+]] -// DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG354]] -// DEBUG1-NEXT: call void @_ZN2S4D1Ev(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]]) #[[ATTR4]], !dbg [[DBG354]] -// DEBUG1-NEXT: ret void, !dbg [[DBG355:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META352:![0-9]+]], metadata !DIExpression()), !dbg [[DBG353:![0-9]+]] +// DEBUG1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG353]] +// DEBUG1-NEXT: call void @_ZN2S4D1Ev(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]]) #[[ATTR4]], !dbg [[DBG353]] +// DEBUG1-NEXT: ret void, !dbg [[DBG354:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S4D1Ev -// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG356:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG355:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META357:![0-9]+]], metadata !DIExpression()), !dbg [[DBG358:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META356:![0-9]+]], metadata !DIExpression()), !dbg [[DBG357:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR4]], !dbg [[DBG359:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG360:![0-9]+]] +// DEBUG1-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR4]], !dbg [[DBG358:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG359:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S4C2Ei -// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG361:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG360:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META362:![0-9]+]], metadata !DIExpression()), !dbg [[DBG363:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META361:![0-9]+]], metadata !DIExpression()), !dbg [[DBG362:![0-9]+]] // DEBUG1-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META364:![0-9]+]], metadata !DIExpression()), !dbg [[DBG365:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META363:![0-9]+]], metadata !DIExpression()), !dbg [[DBG364:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG366:![0-9]+]] -// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG367:![0-9]+]] -// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG366]] -// DEBUG1-NEXT: ret void, !dbg [[DBG368:![0-9]+]] +// DEBUG1-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG365:![0-9]+]] +// DEBUG1-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG366:![0-9]+]] +// DEBUG1-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG365]] +// DEBUG1-NEXT: ret void, !dbg [[DBG367:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_ZN2S4D2Ev -// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG369:![0-9]+]] { +// DEBUG1-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG368:![0-9]+]] { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META370:![0-9]+]], metadata !DIExpression()), !dbg [[DBG371:![0-9]+]] +// DEBUG1-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META369:![0-9]+]], metadata !DIExpression()), !dbg [[DBG370:![0-9]+]] // DEBUG1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG372:![0-9]+]] -// DEBUG1-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG374:![0-9]+]] -// DEBUG1-NEXT: ret void, !dbg [[DBG375:![0-9]+]] +// DEBUG1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG371:![0-9]+]] +// DEBUG1-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG373:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG374:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// DEBUG1-SAME: () #[[ATTR0]] !dbg [[DBG376:![0-9]+]] { +// DEBUG1-SAME: () #[[ATTR0]] !dbg [[DBG375:![0-9]+]] { // DEBUG1-NEXT: entry: -// DEBUG1-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG377:![0-9]+]] -// DEBUG1-NEXT: call void @.__omp_threadprivate_init_.(), !dbg [[DBG377]] -// DEBUG1-NEXT: call void @__cxx_global_var_init.4(), !dbg [[DBG377]] -// DEBUG1-NEXT: call void @__cxx_global_var_init.5(), !dbg [[DBG377]] -// DEBUG1-NEXT: call void @.__omp_threadprivate_init_..3(), !dbg [[DBG377]] +// DEBUG1-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG376:![0-9]+]] +// DEBUG1-NEXT: call void @.__omp_threadprivate_init_.(), !dbg [[DBG376]] +// DEBUG1-NEXT: call void @__cxx_global_var_init.4(), !dbg [[DBG376]] +// DEBUG1-NEXT: call void @__cxx_global_var_init.5(), !dbg [[DBG376]] +// DEBUG1-NEXT: call void @.__omp_threadprivate_init_..3(), !dbg [[DBG376]] // DEBUG1-NEXT: ret void // // // DEBUG2-LABEL: define {{[^@]+}}@__cxx_global_var_init // DEBUG2-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG116:![0-9]+]] { // DEBUG2-NEXT: entry: -// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]), !dbg [[DBG120:![0-9]+]] -// DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB1]], ptr @_ZL3gs1, ptr @.__kmpc_global_ctor_., ptr null, ptr @.__kmpc_global_dtor_.), !dbg [[DBG120]] -// DEBUG2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG121:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR4:[0-9]+]], !dbg [[DBG120]] -// DEBUG2-NEXT: ret void, !dbg [[DBG123:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]), !dbg [[DBG119:![0-9]+]] +// DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB1]], ptr @_ZL3gs1, ptr @.__kmpc_global_ctor_., ptr null, ptr @.__kmpc_global_dtor_.), !dbg [[DBG119]] +// DEBUG2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @_ZL3gs1, i32 noundef 5), !dbg [[DBG120:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S1D1Ev, ptr @_ZL3gs1, ptr @__dso_handle) #[[ATTR4:[0-9]+]], !dbg [[DBG119]] +// DEBUG2-NEXT: ret void, !dbg [[DBG122:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_. -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG124:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG123:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META126:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG129:![0-9]+]] -// DEBUG2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 5), !dbg [[DBG130:![0-9]+]] -// DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG129]] -// DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG129]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META125:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG128:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]], i32 noundef 5), !dbg [[DBG129:![0-9]+]] +// DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG128]] +// DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG128]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S1C1Ei -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG131:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 !dbg [[DBG130:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG134:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META135:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META134:![0-9]+]], metadata !DIExpression()), !dbg [[DBG135:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG137:![0-9]+]] -// DEBUG2-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG137]] -// DEBUG2-NEXT: ret void, !dbg [[DBG138:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG136:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S1C2Ei(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG136]] +// DEBUG2-NEXT: ret void, !dbg [[DBG137:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_. -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG139:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG138:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META140:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG141]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR4]], !dbg [[DBG141]] -// DEBUG2-NEXT: ret void, !dbg [[DBG142:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META139:![0-9]+]], metadata !DIExpression()), !dbg [[DBG140:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG140]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR4]], !dbg [[DBG140]] +// DEBUG2-NEXT: ret void, !dbg [[DBG141:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S1D1Ev -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3:[0-9]+]] comdat align 2 !dbg [[DBG143:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3:[0-9]+]] comdat align 2 !dbg [[DBG142:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META144:![0-9]+]], metadata !DIExpression()), !dbg [[DBG145:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META143:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]], !dbg [[DBG146:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG147:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S1D2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR4]], !dbg [[DBG145:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG146:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 -// DEBUG2-SAME: () #[[ATTR0]] !dbg [[DBG148:![0-9]+]] { +// DEBUG2-SAME: () #[[ATTR0]] !dbg [[DBG147:![0-9]+]] { // DEBUG2-NEXT: entry: -// DEBUG2-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG149:![0-9]+]] -// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG151:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG152:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S2C1Ei(ptr noundef nonnull align 8 dereferenceable(16) @_ZL3gs2, i32 noundef 27), !dbg [[DBG148:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S2D1Ev, ptr @_ZL3gs2, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG150:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG151:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S2C1Ei -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG153:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG152:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META154:![0-9]+]], metadata !DIExpression()), !dbg [[DBG156:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META153:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META157:![0-9]+]], metadata !DIExpression()), !dbg [[DBG158:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META156:![0-9]+]], metadata !DIExpression()), !dbg [[DBG157:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG159:![0-9]+]] -// DEBUG2-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG159]] -// DEBUG2-NEXT: ret void, !dbg [[DBG160:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG158:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S2C2Ei(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG158]] +// DEBUG2-NEXT: ret void, !dbg [[DBG159:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S2D1Ev -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG161:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG160:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META162:![0-9]+]], metadata !DIExpression()), !dbg [[DBG163:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META161:![0-9]+]], metadata !DIExpression()), !dbg [[DBG162:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR4]], !dbg [[DBG164:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG165:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S2D2Ev(ptr noundef nonnull align 8 dereferenceable(16) [[THIS1]]) #[[ATTR4]], !dbg [[DBG163:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG164:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@__cxx_global_var_init.2 -// DEBUG2-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG166:![0-9]+]] { +// DEBUG2-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG165:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT1:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT5:%.*]] = alloca ptr, align 8 -// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3:[0-9]+]]), !dbg [[DBG167:![0-9]+]] -// DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB3]], ptr @arr_x, ptr @.__kmpc_global_ctor_..3, ptr null, ptr @.__kmpc_global_dtor_..4), !dbg [[DBG167]] -// DEBUG2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG168:![0-9]+]] -// DEBUG2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG170:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3:[0-9]+]]), !dbg [[DBG166:![0-9]+]] +// DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB3]], ptr @arr_x, ptr @.__kmpc_global_ctor_..3, ptr null, ptr @.__kmpc_global_dtor_..4), !dbg [[DBG166]] +// DEBUG2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG167:![0-9]+]] +// DEBUG2-NEXT: store ptr @arr_x, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG169:![0-9]+]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) @arr_x, i32 noundef 1) -// DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG171:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG170:![0-9]+]] // DEBUG2: invoke.cont: -// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG170]] +// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG169]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 1), i32 noundef 2) -// DEBUG2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG172:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]], !dbg [[DBG171:![0-9]+]] // DEBUG2: invoke.cont2: -// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG170]] +// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG169]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr @arr_x, i64 2), i32 noundef 3) -// DEBUG2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG173:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG172:![0-9]+]] // DEBUG2: invoke.cont3: -// DEBUG2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG168]] -// DEBUG2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG174:![0-9]+]] +// DEBUG2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG167]] +// DEBUG2-NEXT: store ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG173:![0-9]+]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i32 noundef 4) -// DEBUG2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG175:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD6:%.*]], !dbg [[DBG174:![0-9]+]] // DEBUG2: invoke.cont7: -// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG174]] +// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG173]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 1), i32 noundef 5) -// DEBUG2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG176:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT8:%.*]] unwind label [[LPAD6]], !dbg [[DBG175:![0-9]+]] // DEBUG2: invoke.cont8: -// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG174]] +// DEBUG2-NEXT: store ptr getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG173]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) getelementptr inbounds ([[STRUCT_S1]], ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), i64 2), i32 noundef 6) -// DEBUG2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG177:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT9:%.*]] unwind label [[LPAD6]], !dbg [[DBG176:![0-9]+]] // DEBUG2: invoke.cont9: -// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG167]] -// DEBUG2-NEXT: ret void, !dbg [[DBG167]] +// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG166]] +// DEBUG2-NEXT: ret void, !dbg [[DBG166]] // DEBUG2: lpad: // DEBUG2-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } -// DEBUG2-NEXT: cleanup, !dbg [[DBG178:![0-9]+]] -// DEBUG2-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0, !dbg [[DBG178]] -// DEBUG2-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG178]] -// DEBUG2-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1, !dbg [[DBG178]] -// DEBUG2-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG178]] -// DEBUG2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG170]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP5]], !dbg [[DBG170]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG170]] +// DEBUG2-NEXT: cleanup, !dbg [[DBG177:![0-9]+]] +// DEBUG2-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0, !dbg [[DBG177]] +// DEBUG2-NEXT: store ptr [[TMP3]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG177]] +// DEBUG2-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1, !dbg [[DBG177]] +// DEBUG2-NEXT: store i32 [[TMP4]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG177]] +// DEBUG2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT1]], align 8, !dbg [[DBG169]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @arr_x, [[TMP5]], !dbg [[DBG169]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE4:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG169]] // DEBUG2: arraydestroy.body: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP5]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG170]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG170]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG170]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG170]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG170]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP5]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG169]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG169]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG169]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG169]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE4]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG169]] // DEBUG2: arraydestroy.done4: -// DEBUG2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG170]] +// DEBUG2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG169]] // DEBUG2: lpad6: // DEBUG2-NEXT: [[TMP6:%.*]] = landingpad { ptr, i32 } -// DEBUG2-NEXT: cleanup, !dbg [[DBG178]] -// DEBUG2-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0, !dbg [[DBG178]] -// DEBUG2-NEXT: store ptr [[TMP7]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG178]] -// DEBUG2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1, !dbg [[DBG178]] -// DEBUG2-NEXT: store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG178]] -// DEBUG2-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG174]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP9]], !dbg [[DBG174]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG174]] +// DEBUG2-NEXT: cleanup, !dbg [[DBG177]] +// DEBUG2-NEXT: [[TMP7:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 0, !dbg [[DBG177]] +// DEBUG2-NEXT: store ptr [[TMP7]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG177]] +// DEBUG2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP6]], 1, !dbg [[DBG177]] +// DEBUG2-NEXT: store i32 [[TMP8]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG177]] +// DEBUG2-NEXT: [[TMP9:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT5]], align 8, !dbg [[DBG173]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY10:%.*]] = icmp eq ptr getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), [[TMP9]], !dbg [[DBG173]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY10]], label [[ARRAYDESTROY_DONE15:%.*]], label [[ARRAYDESTROY_BODY11:%.*]], !dbg [[DBG173]] // DEBUG2: arraydestroy.body11: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP9]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG174]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG174]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR4]], !dbg [[DBG174]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG174]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG174]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST12:%.*]] = phi ptr [ [[TMP9]], [[LPAD6]] ], [ [[ARRAYDESTROY_ELEMENT13:%.*]], [[ARRAYDESTROY_BODY11]] ], !dbg [[DBG173]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT13]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST12]], i64 -1, !dbg [[DBG173]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT13]]) #[[ATTR4]], !dbg [[DBG173]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE14:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT13]], getelementptr inbounds ([3 x %struct.S1], ptr @arr_x, i64 1), !dbg [[DBG173]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE14]], label [[ARRAYDESTROY_DONE15]], label [[ARRAYDESTROY_BODY11]], !dbg [[DBG173]] // DEBUG2: arraydestroy.done15: -// DEBUG2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG174]] +// DEBUG2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG173]] // DEBUG2: ehcleanup: -// DEBUG2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG168]] -// DEBUG2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP10]], i64 0, i64 0, !dbg [[DBG168]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG168]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG168]] +// DEBUG2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG167]] +// DEBUG2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP10]], i64 0, i64 0, !dbg [[DBG167]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr @arr_x, [[PAD_ARRAYEND]], !dbg [[DBG167]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG167]] // DEBUG2: arraydestroy.body17: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG168]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG168]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG168]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG168]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG168]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG167]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG167]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG167]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], @arr_x, !dbg [[DBG167]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG167]] // DEBUG2: arraydestroy.done21: -// DEBUG2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG168]] +// DEBUG2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG167]] // DEBUG2: eh.resume: -// DEBUG2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG168]] -// DEBUG2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG168]] -// DEBUG2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG168]] -// DEBUG2-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG168]] -// DEBUG2-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG168]] +// DEBUG2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG167]] +// DEBUG2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG167]] +// DEBUG2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG167]] +// DEBUG2-NEXT: [[LPAD_VAL22:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG167]] +// DEBUG2-NEXT: resume { ptr, i32 } [[LPAD_VAL22]], !dbg [[DBG167]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_..3 -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG179:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] personality ptr @__gxx_personality_v0 !dbg [[DBG178:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT:%.*]] = alloca ptr, align 8 @@ -7372,136 +7372,136 @@ int foobar() { // DEBUG2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: [[ARRAYINIT_ENDOFINIT9:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META180:![0-9]+]], metadata !DIExpression()), !dbg [[DBG181:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG182:![0-9]+]] -// DEBUG2-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG183:![0-9]+]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG184:![0-9]+]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG184]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META179:![0-9]+]], metadata !DIExpression()), !dbg [[DBG180:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG181:![0-9]+]] +// DEBUG2-NEXT: [[ARRAYINIT_BEGIN:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP1]], i64 0, i64 0, !dbg [[DBG182:![0-9]+]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYINIT_BEGIN1:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG183:![0-9]+]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN1]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN1]], i32 noundef 1) -// DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG185:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG184:![0-9]+]] // DEBUG2: invoke.cont: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1, !dbg [[DBG184]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG184]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[ARRAYINIT_BEGIN1]], i64 1, !dbg [[DBG183]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT]], i32 noundef 2) -// DEBUG2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG186:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]], !dbg [[DBG185:![0-9]+]] // DEBUG2: invoke.cont3: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1, !dbg [[DBG184]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG184]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT4:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT]], i64 1, !dbg [[DBG183]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT4]], ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT4]], i32 noundef 3) -// DEBUG2-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]], !dbg [[DBG187:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT5:%.*]] unwind label [[LPAD]], !dbg [[DBG186:![0-9]+]] // DEBUG2: invoke.cont5: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1, !dbg [[DBG183]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0, !dbg [[DBG188:![0-9]+]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG188]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT7:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 1, !dbg [[DBG182]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT7]], ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYINIT_BEGIN8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_ELEMENT7]], i64 0, i64 0, !dbg [[DBG187:![0-9]+]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_BEGIN8]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_BEGIN8]], i32 noundef 4) -// DEBUG2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]], !dbg [[DBG189:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT11:%.*]] unwind label [[LPAD10:%.*]], !dbg [[DBG188:![0-9]+]] // DEBUG2: invoke.cont11: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1, !dbg [[DBG188]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG188]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT12:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_BEGIN8]], i64 1, !dbg [[DBG187]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT12]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT12]], i32 noundef 5) -// DEBUG2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]], !dbg [[DBG190:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT13:%.*]] unwind label [[LPAD10]], !dbg [[DBG189:![0-9]+]] // DEBUG2: invoke.cont13: -// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1, !dbg [[DBG188]] -// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG188]] +// DEBUG2-NEXT: [[ARRAYINIT_ELEMENT14:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYINIT_ELEMENT12]], i64 1, !dbg [[DBG187]] +// DEBUG2-NEXT: store ptr [[ARRAYINIT_ELEMENT14]], ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] // DEBUG2-NEXT: invoke void @_ZN2S1C1Ei(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYINIT_ELEMENT14]], i32 noundef 6) -// DEBUG2-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]], !dbg [[DBG191:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT15:%.*]] unwind label [[LPAD10]], !dbg [[DBG190:![0-9]+]] // DEBUG2: invoke.cont15: -// DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG182]] -// DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG182]] +// DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG181]] +// DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG181]] // DEBUG2: lpad: // DEBUG2-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 } -// DEBUG2-NEXT: cleanup, !dbg [[DBG181]] -// DEBUG2-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0, !dbg [[DBG181]] -// DEBUG2-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG181]] -// DEBUG2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1, !dbg [[DBG181]] -// DEBUG2-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG181]] -// DEBUG2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG184]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN1]], [[TMP6]], !dbg [[DBG184]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE6:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG184]] +// DEBUG2-NEXT: cleanup, !dbg [[DBG180]] +// DEBUG2-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0, !dbg [[DBG180]] +// DEBUG2-NEXT: store ptr [[TMP4]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG180]] +// DEBUG2-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1, !dbg [[DBG180]] +// DEBUG2-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG180]] +// DEBUG2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT2]], align 8, !dbg [[DBG183]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN1]], [[TMP6]], !dbg [[DBG183]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE6:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG183]] // DEBUG2: arraydestroy.body: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP6]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG184]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG184]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG184]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAYINIT_BEGIN1]], !dbg [[DBG184]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE6]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG184]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP6]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG183]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG183]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG183]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAYINIT_BEGIN1]], !dbg [[DBG183]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE6]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG183]] // DEBUG2: arraydestroy.done6: -// DEBUG2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG184]] +// DEBUG2-NEXT: br label [[EHCLEANUP:%.*]], !dbg [[DBG183]] // DEBUG2: lpad10: // DEBUG2-NEXT: [[TMP7:%.*]] = landingpad { ptr, i32 } -// DEBUG2-NEXT: cleanup, !dbg [[DBG181]] -// DEBUG2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0, !dbg [[DBG181]] -// DEBUG2-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG181]] -// DEBUG2-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1, !dbg [[DBG181]] -// DEBUG2-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG181]] -// DEBUG2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG188]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN8]], [[TMP10]], !dbg [[DBG188]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG188]] +// DEBUG2-NEXT: cleanup, !dbg [[DBG180]] +// DEBUG2-NEXT: [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 0, !dbg [[DBG180]] +// DEBUG2-NEXT: store ptr [[TMP8]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG180]] +// DEBUG2-NEXT: [[TMP9:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1, !dbg [[DBG180]] +// DEBUG2-NEXT: store i32 [[TMP9]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG180]] +// DEBUG2-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT9]], align 8, !dbg [[DBG187]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY16:%.*]] = icmp eq ptr [[ARRAYINIT_BEGIN8]], [[TMP10]], !dbg [[DBG187]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY16]], label [[ARRAYDESTROY_DONE21:%.*]], label [[ARRAYDESTROY_BODY17:%.*]], !dbg [[DBG187]] // DEBUG2: arraydestroy.body17: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[TMP10]], [[LPAD10]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG188]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG188]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG188]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], [[ARRAYINIT_BEGIN8]], !dbg [[DBG188]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG188]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST18:%.*]] = phi ptr [ [[TMP10]], [[LPAD10]] ], [ [[ARRAYDESTROY_ELEMENT19:%.*]], [[ARRAYDESTROY_BODY17]] ], !dbg [[DBG187]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT19]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST18]], i64 -1, !dbg [[DBG187]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT19]]) #[[ATTR4]], !dbg [[DBG187]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE20:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT19]], [[ARRAYINIT_BEGIN8]], !dbg [[DBG187]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE20]], label [[ARRAYDESTROY_DONE21]], label [[ARRAYDESTROY_BODY17]], !dbg [[DBG187]] // DEBUG2: arraydestroy.done21: -// DEBUG2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG188]] +// DEBUG2-NEXT: br label [[EHCLEANUP]], !dbg [[DBG187]] // DEBUG2: ehcleanup: -// DEBUG2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG183]] -// DEBUG2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP11]], i64 0, i64 0, !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY22:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]], !dbg [[DBG183]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY22]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY23:%.*]], !dbg [[DBG183]] +// DEBUG2-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARRAYINIT_ENDOFINIT]], align 8, !dbg [[DBG182]] +// DEBUG2-NEXT: [[PAD_ARRAYBEGIN:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYINIT_BEGIN]], i64 0, i64 0, !dbg [[DBG182]] +// DEBUG2-NEXT: [[PAD_ARRAYEND:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[TMP11]], i64 0, i64 0, !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ISEMPTY22:%.*]] = icmp eq ptr [[PAD_ARRAYBEGIN]], [[PAD_ARRAYEND]], !dbg [[DBG182]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY22]], label [[ARRAYDESTROY_DONE27:%.*]], label [[ARRAYDESTROY_BODY23:%.*]], !dbg [[DBG182]] // DEBUG2: arraydestroy.body23: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST24:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT25:%.*]], [[ARRAYDESTROY_BODY23]] ], !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT25]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST24]], i64 -1, !dbg [[DBG183]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT25]]) #[[ATTR4]], !dbg [[DBG183]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE26:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT25]], [[PAD_ARRAYBEGIN]], !dbg [[DBG183]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE26]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY23]], !dbg [[DBG183]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST24:%.*]] = phi ptr [ [[PAD_ARRAYEND]], [[EHCLEANUP]] ], [ [[ARRAYDESTROY_ELEMENT25:%.*]], [[ARRAYDESTROY_BODY23]] ], !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT25]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST24]], i64 -1, !dbg [[DBG182]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT25]]) #[[ATTR4]], !dbg [[DBG182]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE26:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT25]], [[PAD_ARRAYBEGIN]], !dbg [[DBG182]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE26]], label [[ARRAYDESTROY_DONE27]], label [[ARRAYDESTROY_BODY23]], !dbg [[DBG182]] // DEBUG2: arraydestroy.done27: -// DEBUG2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG183]] +// DEBUG2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG182]] // DEBUG2: eh.resume: -// DEBUG2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG183]] -// DEBUG2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG183]] -// DEBUG2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG183]] -// DEBUG2-NEXT: [[LPAD_VAL28:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG183]] -// DEBUG2-NEXT: resume { ptr, i32 } [[LPAD_VAL28]], !dbg [[DBG183]] +// DEBUG2-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8, !dbg [[DBG182]] +// DEBUG2-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG182]] +// DEBUG2-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0, !dbg [[DBG182]] +// DEBUG2-NEXT: [[LPAD_VAL28:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG182]] +// DEBUG2-NEXT: resume { ptr, i32 } [[LPAD_VAL28]], !dbg [[DBG182]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..4 -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG192:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG191:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META193:![0-9]+]], metadata !DIExpression()), !dbg [[DBG194:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG194]] -// DEBUG2-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 6, !dbg [[DBG194]] -// DEBUG2-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG194]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META192:![0-9]+]], metadata !DIExpression()), !dbg [[DBG193:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG193]] +// DEBUG2-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP1]], i64 6, !dbg [[DBG193]] +// DEBUG2-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG193]] // DEBUG2: arraydestroy.body: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG194]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG194]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG194]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[TMP1]], !dbg [[DBG194]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG194]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG193]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG193]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG193]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[TMP1]], !dbg [[DBG193]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG193]] // DEBUG2: arraydestroy.done1: -// DEBUG2-NEXT: ret void, !dbg [[DBG195:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG194:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG196:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG195:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META199:![0-9]+]], metadata !DIExpression()), !dbg [[DBG200:![0-9]+]] -// DEBUG2-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG200]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META198:![0-9]+]], metadata !DIExpression()), !dbg [[DBG199:![0-9]+]] +// DEBUG2-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG199]] // DEBUG2: arraydestroy.body: -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG200]] -// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG200]] -// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG200]] -// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG200]] -// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG200]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[STRUCT_S1:%.*]], ptr @arr_x, i64 6), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG199]] +// DEBUG2-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG199]] +// DEBUG2-NEXT: call void @_ZN2S1D1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR4]], !dbg [[DBG199]] +// DEBUG2-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @arr_x, !dbg [[DBG199]] +// DEBUG2-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG199]] // DEBUG2: arraydestroy.done1: -// DEBUG2-NEXT: ret void, !dbg [[DBG200]] +// DEBUG2-NEXT: ret void, !dbg [[DBG199]] // // // DEBUG2-LABEL: define {{[^@]+}}@main @@ -7511,9 +7511,9 @@ int foobar() { // DEBUG2-NEXT: [[RES:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB9:[0-9]+]]) +// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB9:[0-9]+]]), !dbg [[DBG200:![0-9]+]] // DEBUG2-NEXT: store i32 0, ptr [[RETVAL]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META201:![0-9]+]], metadata !DIExpression()), !dbg [[DBG202:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META201:![0-9]+]], metadata !DIExpression()), !dbg [[DBG202:![0-9]+]] // DEBUG2-NEXT: [[TMP1:%.*]] = load atomic i8, ptr @_ZGVZ4mainE2sm acquire, align 8, !dbg [[DBG203:![0-9]+]] // DEBUG2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP1]], 0, !dbg [[DBG203]] // DEBUG2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG203]], !prof [[PROF204:![0-9]+]] @@ -7524,76 +7524,76 @@ int foobar() { // DEBUG2: init: // DEBUG2-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB7:[0-9]+]]), !dbg [[DBG203]] // DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB7]], ptr @_ZZ4mainE2sm, ptr @.__kmpc_global_ctor_..5, ptr null, ptr @.__kmpc_global_dtor_..6), !dbg [[DBG203]] -// DEBUG2-NEXT: [[TMP4:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB9]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG205:![0-9]+]] -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP4]], i32 0, i32 0, !dbg [[DBG206:![0-9]+]] -// DEBUG2-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG206]] +// DEBUG2-NEXT: [[TMP4:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB9]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG200]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP4]], i32 0, i32 0, !dbg [[DBG205:![0-9]+]] +// DEBUG2-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG205]] // DEBUG2-NEXT: invoke void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) @_ZZ4mainE2sm, i32 noundef [[TMP5]]) -// DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG207:![0-9]+]] +// DEBUG2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG206:![0-9]+]] // DEBUG2: invoke.cont: // DEBUG2-NEXT: [[TMP6:%.*]] = call i32 @__cxa_atexit(ptr @_ZZ4mainEN5SmainD1Ev, ptr @_ZZ4mainE2sm, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG203]] // DEBUG2-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ4mainE2sm) #[[ATTR4]], !dbg [[DBG203]] // DEBUG2-NEXT: br label [[INIT_END]], !dbg [[DBG203]] // DEBUG2: init.end: -// DEBUG2-NEXT: [[TMP7:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB11:[0-9]+]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG208:![0-9]+]] -// DEBUG2-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP7]], i32 0, i32 0, !dbg [[DBG209:![0-9]+]] -// DEBUG2-NEXT: [[TMP8:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG209]] -// DEBUG2-NEXT: store i32 [[TMP8]], ptr [[RES]], align 4, !dbg [[DBG210:![0-9]+]] -// DEBUG2-NEXT: [[TMP9:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB13:[0-9]+]], i32 [[TMP0]], ptr @_ZZ4mainE2sm, i64 24, ptr @_ZZ4mainE2sm.cache.), !dbg [[DBG211:![0-9]+]] -// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[TMP9]], i32 0, i32 0, !dbg [[DBG212:![0-9]+]] -// DEBUG2-NEXT: [[TMP10:%.*]] = load i32, ptr [[A2]], align 8, !dbg [[DBG212]] -// DEBUG2-NEXT: [[TMP11:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG213:![0-9]+]] -// DEBUG2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP10]], !dbg [[DBG213]] -// DEBUG2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG213]] -// DEBUG2-NEXT: [[TMP12:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB15:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG214:![0-9]+]] -// DEBUG2-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP12]], i32 0, i32 0, !dbg [[DBG215:![0-9]+]] -// DEBUG2-NEXT: [[TMP13:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG215]] -// DEBUG2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG216:![0-9]+]] -// DEBUG2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG216]] -// DEBUG2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG216]] -// DEBUG2-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG217:![0-9]+]] -// DEBUG2-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG218:![0-9]+]] -// DEBUG2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG218]] -// DEBUG2-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG218]] -// DEBUG2-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB17:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG219:![0-9]+]] -// DEBUG2-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP17]], i32 0, i32 0, !dbg [[DBG220:![0-9]+]] -// DEBUG2-NEXT: [[TMP18:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG220]] -// DEBUG2-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG221:![0-9]+]] -// DEBUG2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP19]], [[TMP18]], !dbg [[DBG221]] -// DEBUG2-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG221]] -// DEBUG2-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB19:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG222:![0-9]+]] -// DEBUG2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP20]], i64 0, i64 1, !dbg [[DBG222]] -// DEBUG2-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG222]] -// DEBUG2-NEXT: [[A9:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX8]], i32 0, i32 0, !dbg [[DBG223:![0-9]+]] -// DEBUG2-NEXT: [[TMP21:%.*]] = load i32, ptr [[A9]], align 4, !dbg [[DBG223]] -// DEBUG2-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG224:![0-9]+]] -// DEBUG2-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG224]] -// DEBUG2-NEXT: store i32 [[ADD10]], ptr [[RES]], align 4, !dbg [[DBG224]] -// DEBUG2-NEXT: [[TMP23:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB21:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG225:![0-9]+]] -// DEBUG2-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4, !dbg [[DBG225]] -// DEBUG2-NEXT: [[TMP25:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG226:![0-9]+]] -// DEBUG2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP25]], [[TMP24]], !dbg [[DBG226]] -// DEBUG2-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG226]] -// DEBUG2-NEXT: [[TMP26:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB23:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG227:![0-9]+]] -// DEBUG2-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP26]], align 4, !dbg [[DBG227]] -// DEBUG2-NEXT: [[CONV:%.*]] = fptosi float [[TMP27]] to i32, !dbg [[DBG227]] -// DEBUG2-NEXT: [[TMP28:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG228:![0-9]+]] -// DEBUG2-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP28]], [[CONV]], !dbg [[DBG228]] -// DEBUG2-NEXT: store i32 [[ADD12]], ptr [[RES]], align 4, !dbg [[DBG228]] -// DEBUG2-NEXT: [[TMP29:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB25:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG229:![0-9]+]] -// DEBUG2-NEXT: [[A13:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP29]], i32 0, i32 0, !dbg [[DBG230:![0-9]+]] -// DEBUG2-NEXT: [[TMP30:%.*]] = load i32, ptr [[A13]], align 4, !dbg [[DBG230]] -// DEBUG2-NEXT: [[TMP31:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] -// DEBUG2-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP31]], [[TMP30]], !dbg [[DBG231]] -// DEBUG2-NEXT: store i32 [[ADD14]], ptr [[RES]], align 4, !dbg [[DBG231]] -// DEBUG2-NEXT: [[TMP32:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG232:![0-9]+]] -// DEBUG2-NEXT: ret i32 [[TMP32]], !dbg [[DBG233:![0-9]+]] +// DEBUG2-NEXT: [[TMP7:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB11:[0-9]+]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG207:![0-9]+]] +// DEBUG2-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP7]], i32 0, i32 0, !dbg [[DBG208:![0-9]+]] +// DEBUG2-NEXT: [[TMP8:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG208]] +// DEBUG2-NEXT: store i32 [[TMP8]], ptr [[RES]], align 4, !dbg [[DBG209:![0-9]+]] +// DEBUG2-NEXT: [[TMP9:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB13:[0-9]+]], i32 [[TMP0]], ptr @_ZZ4mainE2sm, i64 24, ptr @_ZZ4mainE2sm.cache.), !dbg [[DBG210:![0-9]+]] +// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[TMP9]], i32 0, i32 0, !dbg [[DBG211:![0-9]+]] +// DEBUG2-NEXT: [[TMP10:%.*]] = load i32, ptr [[A2]], align 8, !dbg [[DBG211]] +// DEBUG2-NEXT: [[TMP11:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG212:![0-9]+]] +// DEBUG2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP10]], !dbg [[DBG212]] +// DEBUG2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG212]] +// DEBUG2-NEXT: [[TMP12:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB15:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG213:![0-9]+]] +// DEBUG2-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[TMP12]], i32 0, i32 0, !dbg [[DBG214:![0-9]+]] +// DEBUG2-NEXT: [[TMP13:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG214]] +// DEBUG2-NEXT: [[TMP14:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG215:![0-9]+]] +// DEBUG2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP14]], [[TMP13]], !dbg [[DBG215]] +// DEBUG2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG215]] +// DEBUG2-NEXT: [[TMP15:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG216:![0-9]+]] +// DEBUG2-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG217:![0-9]+]] +// DEBUG2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG217]] +// DEBUG2-NEXT: store i32 [[ADD5]], ptr [[RES]], align 4, !dbg [[DBG217]] +// DEBUG2-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB17:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG218:![0-9]+]] +// DEBUG2-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP17]], i32 0, i32 0, !dbg [[DBG219:![0-9]+]] +// DEBUG2-NEXT: [[TMP18:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG219]] +// DEBUG2-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG220:![0-9]+]] +// DEBUG2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP19]], [[TMP18]], !dbg [[DBG220]] +// DEBUG2-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG220]] +// DEBUG2-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB19:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG221:![0-9]+]] +// DEBUG2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP20]], i64 0, i64 1, !dbg [[DBG221]] +// DEBUG2-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG221]] +// DEBUG2-NEXT: [[A9:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX8]], i32 0, i32 0, !dbg [[DBG222:![0-9]+]] +// DEBUG2-NEXT: [[TMP21:%.*]] = load i32, ptr [[A9]], align 4, !dbg [[DBG222]] +// DEBUG2-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG223:![0-9]+]] +// DEBUG2-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG223]] +// DEBUG2-NEXT: store i32 [[ADD10]], ptr [[RES]], align 4, !dbg [[DBG223]] +// DEBUG2-NEXT: [[TMP23:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB21:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG224:![0-9]+]] +// DEBUG2-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4, !dbg [[DBG224]] +// DEBUG2-NEXT: [[TMP25:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG225:![0-9]+]] +// DEBUG2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP25]], [[TMP24]], !dbg [[DBG225]] +// DEBUG2-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG225]] +// DEBUG2-NEXT: [[TMP26:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB23:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG226:![0-9]+]] +// DEBUG2-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP26]], align 4, !dbg [[DBG226]] +// DEBUG2-NEXT: [[CONV:%.*]] = fptosi float [[TMP27]] to i32, !dbg [[DBG226]] +// DEBUG2-NEXT: [[TMP28:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG227:![0-9]+]] +// DEBUG2-NEXT: [[ADD12:%.*]] = add nsw i32 [[TMP28]], [[CONV]], !dbg [[DBG227]] +// DEBUG2-NEXT: store i32 [[ADD12]], ptr [[RES]], align 4, !dbg [[DBG227]] +// DEBUG2-NEXT: [[TMP29:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB25:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG228:![0-9]+]] +// DEBUG2-NEXT: [[A13:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP29]], i32 0, i32 0, !dbg [[DBG229:![0-9]+]] +// DEBUG2-NEXT: [[TMP30:%.*]] = load i32, ptr [[A13]], align 4, !dbg [[DBG229]] +// DEBUG2-NEXT: [[TMP31:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG230:![0-9]+]] +// DEBUG2-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP31]], [[TMP30]], !dbg [[DBG230]] +// DEBUG2-NEXT: store i32 [[ADD14]], ptr [[RES]], align 4, !dbg [[DBG230]] +// DEBUG2-NEXT: [[TMP32:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG231:![0-9]+]] +// DEBUG2-NEXT: ret i32 [[TMP32]], !dbg [[DBG232:![0-9]+]] // DEBUG2: lpad: // DEBUG2-NEXT: [[TMP33:%.*]] = landingpad { ptr, i32 } -// DEBUG2-NEXT: cleanup, !dbg [[DBG234:![0-9]+]] -// DEBUG2-NEXT: [[TMP34:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 0, !dbg [[DBG234]] -// DEBUG2-NEXT: store ptr [[TMP34]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG234]] -// DEBUG2-NEXT: [[TMP35:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 1, !dbg [[DBG234]] -// DEBUG2-NEXT: store i32 [[TMP35]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG234]] +// DEBUG2-NEXT: cleanup, !dbg [[DBG233:![0-9]+]] +// DEBUG2-NEXT: [[TMP34:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 0, !dbg [[DBG233]] +// DEBUG2-NEXT: store ptr [[TMP34]], ptr [[EXN_SLOT]], align 8, !dbg [[DBG233]] +// DEBUG2-NEXT: [[TMP35:%.*]] = extractvalue { ptr, i32 } [[TMP33]], 1, !dbg [[DBG233]] +// DEBUG2-NEXT: store i32 [[TMP35]], ptr [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG233]] // DEBUG2-NEXT: call void @__cxa_guard_abort(ptr @_ZGVZ4mainE2sm) #[[ATTR4]], !dbg [[DBG203]] // DEBUG2-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG203]] // DEBUG2: eh.resume: @@ -7605,296 +7605,296 @@ int foobar() { // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_..5 -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG235:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG234:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 -// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB5:[0-9]+]]) +// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB5:[0-9]+]]), !dbg [[DBG235:![0-9]+]] // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META236:![0-9]+]], metadata !DIExpression()), !dbg [[DBG237:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META236:![0-9]+]], metadata !DIExpression()), !dbg [[DBG237:![0-9]+]] // DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG238:![0-9]+]] -// DEBUG2-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB5]], i32 [[TMP1]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG239:![0-9]+]] -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG240:![0-9]+]] -// DEBUG2-NEXT: [[TMP4:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG240]] -// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) [[TMP2]], i32 noundef [[TMP4]]), !dbg [[DBG241:![0-9]+]] +// DEBUG2-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB5]], i32 [[TMP1]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG235]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG239:![0-9]+]] +// DEBUG2-NEXT: [[TMP4:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG239]] +// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainC1Ei(ptr noundef nonnull align 8 dereferenceable(24) [[TMP2]], i32 noundef [[TMP4]]), !dbg [[DBG240:![0-9]+]] // DEBUG2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG238]] // DEBUG2-NEXT: ret ptr [[TMP5]], !dbg [[DBG238]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC1Ei -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG242:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG241:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META243:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META242:![0-9]+]], metadata !DIExpression()), !dbg [[DBG244:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META246:![0-9]+]], metadata !DIExpression()), !dbg [[DBG247:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META245:![0-9]+]], metadata !DIExpression()), !dbg [[DBG246:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG248:![0-9]+]] -// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG248]] -// DEBUG2-NEXT: ret void, !dbg [[DBG249:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG247:![0-9]+]] +// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainC2Ei(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG247]] +// DEBUG2-NEXT: ret void, !dbg [[DBG248:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..6 -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG250:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG249:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META251:![0-9]+]], metadata !DIExpression()), !dbg [[DBG252:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG252]] -// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainD1Ev(ptr noundef nonnull align 8 dereferenceable(24) [[TMP1]]) #[[ATTR4]], !dbg [[DBG252]] -// DEBUG2-NEXT: ret void, !dbg [[DBG253:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META250:![0-9]+]], metadata !DIExpression()), !dbg [[DBG251:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG251]] +// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainD1Ev(ptr noundef nonnull align 8 dereferenceable(24) [[TMP1]]) #[[ATTR4]], !dbg [[DBG251]] +// DEBUG2-NEXT: ret void, !dbg [[DBG252:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD1Ev -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG254:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG253:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META255:![0-9]+]], metadata !DIExpression()), !dbg [[DBG256:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META254:![0-9]+]], metadata !DIExpression()), !dbg [[DBG255:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR4]], !dbg [[DBG257:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG258:![0-9]+]] +// DEBUG2-NEXT: call void @_ZZ4mainEN5SmainD2Ev(ptr noundef nonnull align 8 dereferenceable(24) [[THIS1]]) #[[ATTR4]], !dbg [[DBG256:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG257:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_Z6foobarv -// DEBUG2-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG259:![0-9]+]] { +// DEBUG2-SAME: () #[[ATTR3]] !dbg [[DBG258:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[RES:%.*]] = alloca i32, align 4 -// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB27:[0-9]+]]) -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META260:![0-9]+]], metadata !DIExpression()), !dbg [[DBG261:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB27]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG262:![0-9]+]] -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP1]], i32 0, i32 0, !dbg [[DBG263:![0-9]+]] -// DEBUG2-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG263]] -// DEBUG2-NEXT: store i32 [[TMP2]], ptr [[RES]], align 4, !dbg [[DBG264:![0-9]+]] -// DEBUG2-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB29:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG265:![0-9]+]] -// DEBUG2-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG266:![0-9]+]] -// DEBUG2-NEXT: [[TMP4:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG266]] -// DEBUG2-NEXT: [[TMP5:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG267:![0-9]+]] -// DEBUG2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP4]], !dbg [[DBG267]] -// DEBUG2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG267]] -// DEBUG2-NEXT: [[TMP6:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG268:![0-9]+]] -// DEBUG2-NEXT: [[TMP7:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG269:![0-9]+]] -// DEBUG2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP7]], [[TMP6]], !dbg [[DBG269]] -// DEBUG2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG269]] -// DEBUG2-NEXT: [[TMP8:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB31:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG270:![0-9]+]] -// DEBUG2-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP8]], i32 0, i32 0, !dbg [[DBG271:![0-9]+]] -// DEBUG2-NEXT: [[TMP9:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG271]] -// DEBUG2-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG272:![0-9]+]] -// DEBUG2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG272]] -// DEBUG2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG272]] -// DEBUG2-NEXT: [[TMP11:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB33:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG273:![0-9]+]] -// DEBUG2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP11]], i64 0, i64 1, !dbg [[DBG273]] -// DEBUG2-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG273]] -// DEBUG2-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX5]], i32 0, i32 0, !dbg [[DBG274:![0-9]+]] -// DEBUG2-NEXT: [[TMP12:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG274]] -// DEBUG2-NEXT: [[TMP13:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG275:![0-9]+]] -// DEBUG2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP13]], [[TMP12]], !dbg [[DBG275]] -// DEBUG2-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG275]] -// DEBUG2-NEXT: [[TMP14:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB35:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG276:![0-9]+]] -// DEBUG2-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4, !dbg [[DBG276]] -// DEBUG2-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG277:![0-9]+]] -// DEBUG2-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG277]] -// DEBUG2-NEXT: store i32 [[ADD8]], ptr [[RES]], align 4, !dbg [[DBG277]] -// DEBUG2-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB37:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG278:![0-9]+]] -// DEBUG2-NEXT: [[TMP18:%.*]] = load float, ptr [[TMP17]], align 4, !dbg [[DBG278]] -// DEBUG2-NEXT: [[CONV:%.*]] = fptosi float [[TMP18]] to i32, !dbg [[DBG278]] -// DEBUG2-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG279:![0-9]+]] -// DEBUG2-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP19]], [[CONV]], !dbg [[DBG279]] -// DEBUG2-NEXT: store i32 [[ADD9]], ptr [[RES]], align 4, !dbg [[DBG279]] -// DEBUG2-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB39:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG280:![0-9]+]] -// DEBUG2-NEXT: [[A10:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP20]], i32 0, i32 0, !dbg [[DBG281:![0-9]+]] -// DEBUG2-NEXT: [[TMP21:%.*]] = load i32, ptr [[A10]], align 4, !dbg [[DBG281]] -// DEBUG2-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG282:![0-9]+]] -// DEBUG2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG282]] -// DEBUG2-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG282]] -// DEBUG2-NEXT: [[TMP23:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG283:![0-9]+]] -// DEBUG2-NEXT: ret i32 [[TMP23]], !dbg [[DBG284:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB27:[0-9]+]]), !dbg [[DBG259:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[RES]], metadata [[META260:![0-9]+]], metadata !DIExpression()), !dbg [[DBG261:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB27]], i32 [[TMP0]], ptr @_ZN6Static1sE, i64 8, ptr @_ZN6Static1sE.cache.), !dbg [[DBG259]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], ptr [[TMP1]], i32 0, i32 0, !dbg [[DBG262:![0-9]+]] +// DEBUG2-NEXT: [[TMP2:%.*]] = load i32, ptr [[A]], align 4, !dbg [[DBG262]] +// DEBUG2-NEXT: store i32 [[TMP2]], ptr [[RES]], align 4, !dbg [[DBG263:![0-9]+]] +// DEBUG2-NEXT: [[TMP3:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB29:[0-9]+]], i32 [[TMP0]], ptr @_ZL3gs1, i64 4, ptr @_ZL3gs1.cache.), !dbg [[DBG264:![0-9]+]] +// DEBUG2-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[TMP3]], i32 0, i32 0, !dbg [[DBG265:![0-9]+]] +// DEBUG2-NEXT: [[TMP4:%.*]] = load i32, ptr [[A1]], align 4, !dbg [[DBG265]] +// DEBUG2-NEXT: [[TMP5:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG266:![0-9]+]] +// DEBUG2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP4]], !dbg [[DBG266]] +// DEBUG2-NEXT: store i32 [[ADD]], ptr [[RES]], align 4, !dbg [[DBG266]] +// DEBUG2-NEXT: [[TMP6:%.*]] = load i32, ptr @_ZL3gs2, align 8, !dbg [[DBG267:![0-9]+]] +// DEBUG2-NEXT: [[TMP7:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG268:![0-9]+]] +// DEBUG2-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP7]], [[TMP6]], !dbg [[DBG268]] +// DEBUG2-NEXT: store i32 [[ADD2]], ptr [[RES]], align 4, !dbg [[DBG268]] +// DEBUG2-NEXT: [[TMP8:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB31:[0-9]+]], i32 [[TMP0]], ptr @gs3, i64 12, ptr @gs3.cache.), !dbg [[DBG269:![0-9]+]] +// DEBUG2-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_S5:%.*]], ptr [[TMP8]], i32 0, i32 0, !dbg [[DBG270:![0-9]+]] +// DEBUG2-NEXT: [[TMP9:%.*]] = load i32, ptr [[A3]], align 4, !dbg [[DBG270]] +// DEBUG2-NEXT: [[TMP10:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG271:![0-9]+]] +// DEBUG2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], [[TMP9]], !dbg [[DBG271]] +// DEBUG2-NEXT: store i32 [[ADD4]], ptr [[RES]], align 4, !dbg [[DBG271]] +// DEBUG2-NEXT: [[TMP11:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB33:[0-9]+]], i32 [[TMP0]], ptr @arr_x, i64 24, ptr @arr_x.cache.), !dbg [[DBG272:![0-9]+]] +// DEBUG2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [3 x %struct.S1]], ptr [[TMP11]], i64 0, i64 1, !dbg [[DBG272]] +// DEBUG2-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [3 x %struct.S1], ptr [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG272]] +// DEBUG2-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[ARRAYIDX5]], i32 0, i32 0, !dbg [[DBG273:![0-9]+]] +// DEBUG2-NEXT: [[TMP12:%.*]] = load i32, ptr [[A6]], align 4, !dbg [[DBG273]] +// DEBUG2-NEXT: [[TMP13:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG274:![0-9]+]] +// DEBUG2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP13]], [[TMP12]], !dbg [[DBG274]] +// DEBUG2-NEXT: store i32 [[ADD7]], ptr [[RES]], align 4, !dbg [[DBG274]] +// DEBUG2-NEXT: [[TMP14:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB35:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIiE2stE, i64 4, ptr @_ZN2STIiE2stE.cache.), !dbg [[DBG275:![0-9]+]] +// DEBUG2-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4, !dbg [[DBG275]] +// DEBUG2-NEXT: [[TMP16:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG276:![0-9]+]] +// DEBUG2-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP16]], [[TMP15]], !dbg [[DBG276]] +// DEBUG2-NEXT: store i32 [[ADD8]], ptr [[RES]], align 4, !dbg [[DBG276]] +// DEBUG2-NEXT: [[TMP17:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB37:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STIfE2stE, i64 4, ptr @_ZN2STIfE2stE.cache.), !dbg [[DBG277:![0-9]+]] +// DEBUG2-NEXT: [[TMP18:%.*]] = load float, ptr [[TMP17]], align 4, !dbg [[DBG277]] +// DEBUG2-NEXT: [[CONV:%.*]] = fptosi float [[TMP18]] to i32, !dbg [[DBG277]] +// DEBUG2-NEXT: [[TMP19:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG278:![0-9]+]] +// DEBUG2-NEXT: [[ADD9:%.*]] = add nsw i32 [[TMP19]], [[CONV]], !dbg [[DBG278]] +// DEBUG2-NEXT: store i32 [[ADD9]], ptr [[RES]], align 4, !dbg [[DBG278]] +// DEBUG2-NEXT: [[TMP20:%.*]] = call ptr @__kmpc_threadprivate_cached(ptr @[[GLOB39:[0-9]+]], i32 [[TMP0]], ptr @_ZN2STI2S4E2stE, i64 8, ptr @_ZN2STI2S4E2stE.cache.), !dbg [[DBG279:![0-9]+]] +// DEBUG2-NEXT: [[A10:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[TMP20]], i32 0, i32 0, !dbg [[DBG280:![0-9]+]] +// DEBUG2-NEXT: [[TMP21:%.*]] = load i32, ptr [[A10]], align 4, !dbg [[DBG280]] +// DEBUG2-NEXT: [[TMP22:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG281:![0-9]+]] +// DEBUG2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]], !dbg [[DBG281]] +// DEBUG2-NEXT: store i32 [[ADD11]], ptr [[RES]], align 4, !dbg [[DBG281]] +// DEBUG2-NEXT: [[TMP23:%.*]] = load i32, ptr [[RES]], align 4, !dbg [[DBG282:![0-9]+]] +// DEBUG2-NEXT: ret i32 [[TMP23]], !dbg [[DBG283:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@__cxx_global_var_init.7 -// DEBUG2-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG285:![0-9]+]] { +// DEBUG2-SAME: () #[[ATTR0]] comdat($_ZN2STI2S4E2stE) !dbg [[DBG284:![0-9]+]] { // DEBUG2-NEXT: entry: -// DEBUG2-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG286:![0-9]+]] -// DEBUG2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG286]] -// DEBUG2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG286]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i8, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG285:![0-9]+]] +// DEBUG2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG285]] +// DEBUG2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG285]] // DEBUG2: init.check: -// DEBUG2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG286]] -// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB41:[0-9]+]]), !dbg [[DBG286]] -// DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB41]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..8, ptr null, ptr @.__kmpc_global_dtor_..9), !dbg [[DBG286]] -// DEBUG2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG287:![0-9]+]] -// DEBUG2-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG286]] -// DEBUG2-NEXT: br label [[INIT_END]], !dbg [[DBG286]] +// DEBUG2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG285]] +// DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB41:[0-9]+]]), !dbg [[DBG285]] +// DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB41]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..8, ptr null, ptr @.__kmpc_global_dtor_..9), !dbg [[DBG285]] +// DEBUG2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG286:![0-9]+]] +// DEBUG2-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG285]] +// DEBUG2-NEXT: br label [[INIT_END]], !dbg [[DBG285]] // DEBUG2: init.end: -// DEBUG2-NEXT: ret void, !dbg [[DBG289:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG288:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_..8 -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG290:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG289:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META291:![0-9]+]], metadata !DIExpression()), !dbg [[DBG292:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG293:![0-9]+]] -// DEBUG2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]], i32 noundef 23), !dbg [[DBG294:![0-9]+]] -// DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG293]] -// DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG293]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META290:![0-9]+]], metadata !DIExpression()), !dbg [[DBG291:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG292:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]], i32 noundef 23), !dbg [[DBG293:![0-9]+]] +// DEBUG2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG292]] +// DEBUG2-NEXT: ret ptr [[TMP2]], !dbg [[DBG292]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S4C1Ei -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG295:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 !dbg [[DBG294:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META296:![0-9]+]], metadata !DIExpression()), !dbg [[DBG298:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META295:![0-9]+]], metadata !DIExpression()), !dbg [[DBG297:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META299:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META298:![0-9]+]], metadata !DIExpression()), !dbg [[DBG299:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG301:![0-9]+]] -// DEBUG2-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG301]] -// DEBUG2-NEXT: ret void, !dbg [[DBG302:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG300:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S4C2Ei(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], i32 noundef [[TMP0]]), !dbg [[DBG300]] +// DEBUG2-NEXT: ret void, !dbg [[DBG301:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@.__kmpc_global_dtor_..9 -// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG303:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] !dbg [[DBG302:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META304:![0-9]+]], metadata !DIExpression()), !dbg [[DBG305:![0-9]+]] -// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG305]] -// DEBUG2-NEXT: call void @_ZN2S4D1Ev(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]]) #[[ATTR4]], !dbg [[DBG305]] -// DEBUG2-NEXT: ret void, !dbg [[DBG306:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[DOTADDR]], metadata [[META303:![0-9]+]], metadata !DIExpression()), !dbg [[DBG304:![0-9]+]] +// DEBUG2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DOTADDR]], align 8, !dbg [[DBG304]] +// DEBUG2-NEXT: call void @_ZN2S4D1Ev(ptr noundef nonnull align 4 dereferenceable(8) [[TMP1]]) #[[ATTR4]], !dbg [[DBG304]] +// DEBUG2-NEXT: ret void, !dbg [[DBG305:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S4D1Ev -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG307:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG306:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META308:![0-9]+]], metadata !DIExpression()), !dbg [[DBG309:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META307:![0-9]+]], metadata !DIExpression()), !dbg [[DBG308:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR4]], !dbg [[DBG310:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG311:![0-9]+]] +// DEBUG2-NEXT: call void @_ZN2S4D2Ev(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR4]], !dbg [[DBG309:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG310:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S1C2Ei -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG312:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG311:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META313:![0-9]+]], metadata !DIExpression()), !dbg [[DBG314:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META312:![0-9]+]], metadata !DIExpression()), !dbg [[DBG313:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META315:![0-9]+]], metadata !DIExpression()), !dbg [[DBG316:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META314:![0-9]+]], metadata !DIExpression()), !dbg [[DBG315:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG317:![0-9]+]] -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG318:![0-9]+]] -// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG317]] -// DEBUG2-NEXT: ret void, !dbg [[DBG319:![0-9]+]] +// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG316:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG317:![0-9]+]] +// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG316]] +// DEBUG2-NEXT: ret void, !dbg [[DBG318:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S1D2Ev -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG320:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG319:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META321:![0-9]+]], metadata !DIExpression()), !dbg [[DBG322:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META320:![0-9]+]], metadata !DIExpression()), !dbg [[DBG321:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG323:![0-9]+]] -// DEBUG2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG325:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG326:![0-9]+]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG322:![0-9]+]] +// DEBUG2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG324:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG325:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S2C2Ei -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG327:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG326:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META328:![0-9]+]], metadata !DIExpression()), !dbg [[DBG329:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META327:![0-9]+]], metadata !DIExpression()), !dbg [[DBG328:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META330:![0-9]+]], metadata !DIExpression()), !dbg [[DBG331:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META329:![0-9]+]], metadata !DIExpression()), !dbg [[DBG330:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG332:![0-9]+]] -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG333:![0-9]+]] -// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG332]] -// DEBUG2-NEXT: ret void, !dbg [[DBG334:![0-9]+]] +// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG331:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG332:![0-9]+]] +// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG331]] +// DEBUG2-NEXT: ret void, !dbg [[DBG333:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S2D2Ev -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG335:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(16) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG334:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META336:![0-9]+]], metadata !DIExpression()), !dbg [[DBG337:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META335:![0-9]+]], metadata !DIExpression()), !dbg [[DBG336:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG338:![0-9]+]] -// DEBUG2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG340:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG341:![0-9]+]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S2:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG337:![0-9]+]] +// DEBUG2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG339:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG340:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainC2Ei -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG342:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG341:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META343:![0-9]+]], metadata !DIExpression()), !dbg [[DBG344:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META342:![0-9]+]], metadata !DIExpression()), !dbg [[DBG343:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META345:![0-9]+]], metadata !DIExpression()), !dbg [[DBG346:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META344:![0-9]+]], metadata !DIExpression()), !dbg [[DBG345:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG347:![0-9]+]] -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG348:![0-9]+]] -// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG347]] -// DEBUG2-NEXT: ret void, !dbg [[DBG349:![0-9]+]] +// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG346:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG347:![0-9]+]] +// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 8, !dbg [[DBG346]] +// DEBUG2-NEXT: ret void, !dbg [[DBG348:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZZ4mainEN5SmainD2Ev -// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG350:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 8 dereferenceable(24) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] align 2 !dbg [[DBG349:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META351:![0-9]+]], metadata !DIExpression()), !dbg [[DBG352:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META350:![0-9]+]], metadata !DIExpression()), !dbg [[DBG351:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG353:![0-9]+]] -// DEBUG2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG355:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG356:![0-9]+]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG352:![0-9]+]] +// DEBUG2-NEXT: store i32 0, ptr [[A]], align 8, !dbg [[DBG354:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG355:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S4C2Ei -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG357:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], i32 noundef [[A:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG356:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META358:![0-9]+]], metadata !DIExpression()), !dbg [[DBG359:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META357:![0-9]+]], metadata !DIExpression()), !dbg [[DBG358:![0-9]+]] // DEBUG2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META360:![0-9]+]], metadata !DIExpression()), !dbg [[DBG361:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[A_ADDR]], metadata [[META359:![0-9]+]], metadata !DIExpression()), !dbg [[DBG360:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG362:![0-9]+]] -// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG363:![0-9]+]] -// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG362]] -// DEBUG2-NEXT: ret void, !dbg [[DBG364:![0-9]+]] +// DEBUG2-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG361:![0-9]+]] +// DEBUG2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4, !dbg [[DBG362:![0-9]+]] +// DEBUG2-NEXT: store i32 [[TMP0]], ptr [[A2]], align 4, !dbg [[DBG361]] +// DEBUG2-NEXT: ret void, !dbg [[DBG363:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_ZN2S4D2Ev -// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG365:![0-9]+]] { +// DEBUG2-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 !dbg [[DBG364:![0-9]+]] { // DEBUG2-NEXT: entry: // DEBUG2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // DEBUG2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META366:![0-9]+]], metadata !DIExpression()), !dbg [[DBG367:![0-9]+]] +// DEBUG2-NEXT: tail call void @llvm.dbg.declare(metadata ptr [[THIS_ADDR]], metadata [[META365:![0-9]+]], metadata !DIExpression()), !dbg [[DBG366:![0-9]+]] // DEBUG2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG368:![0-9]+]] -// DEBUG2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG370:![0-9]+]] -// DEBUG2-NEXT: ret void, !dbg [[DBG371:![0-9]+]] +// DEBUG2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S4:%.*]], ptr [[THIS1]], i32 0, i32 0, !dbg [[DBG367:![0-9]+]] +// DEBUG2-NEXT: store i32 0, ptr [[A]], align 4, !dbg [[DBG369:![0-9]+]] +// DEBUG2-NEXT: ret void, !dbg [[DBG370:![0-9]+]] // // // DEBUG2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_threadprivate_codegen.cpp -// DEBUG2-SAME: () #[[ATTR0]] !dbg [[DBG372:![0-9]+]] { +// DEBUG2-SAME: () #[[ATTR0]] !dbg [[DBG371:![0-9]+]] { // DEBUG2-NEXT: entry: -// DEBUG2-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG373:![0-9]+]] -// DEBUG2-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG373]] -// DEBUG2-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG373]] +// DEBUG2-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG372:![0-9]+]] +// DEBUG2-NEXT: call void @__cxx_global_var_init.1(), !dbg [[DBG372]] +// DEBUG2-NEXT: call void @__cxx_global_var_init.2(), !dbg [[DBG372]] // DEBUG2-NEXT: ret void // diff --git a/clang/test/OpenMP/tile_codegen.cpp b/clang/test/OpenMP/tile_codegen.cpp index 93a3a14133ab5..5fd5609b844cc 100644 --- a/clang/test/OpenMP/tile_codegen.cpp +++ b/clang/test/OpenMP/tile_codegen.cpp @@ -1,10 +1,10 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 4 // Check code generation -// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fclang-abi-compat=latest -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fclang-abi-compat=latest -std=c++20 -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 // Check same results after serialization round-trip -// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fclang-abi-compat=latest -fopenmp -emit-pch -o %t %s -// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fclang-abi-compat=latest -fopenmp -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2 +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fclang-abi-compat=latest -std=c++20 -fopenmp -emit-pch -o %t %s +// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fclang-abi-compat=latest -std=c++20 -fopenmp -include-pch %t -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2 // expected-no-diagnostics #ifndef HEADER @@ -91,22 +91,38 @@ extern "C" void foo8(int a) { } +typedef struct { double array[12]; } data_t; +extern "C" void foo9(data_t data) { +#pragma omp tile sizes(5) + for (double v : data.array) + body(v); +} + + +extern "C" void foo10(data_t data) { +#pragma omp tile sizes(5) + for (double c = 42.0; double v : data.array) + body(c, v); +} + + #endif /* HEADER */ -// CHECK1-LABEL: define {{[^@]+}}@body -// CHECK1-SAME: (...) #[[ATTR0:[0-9]+]] { + +// CHECK1-LABEL: define dso_local void @body( +// CHECK1-SAME: ...) #[[ATTR0:[0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_var_init -// CHECK1-SAME: () #[[ATTR1:[0-9]+]] section ".text.startup" { +// CHECK1-LABEL: define internal void @__cxx_global_var_init( +// CHECK1-SAME: ) #[[ATTR1:[0-9]+]] section ".text.startup" { // CHECK1-NEXT: entry: // CHECK1-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s) // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC1Ev -// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 { +// CHECK1-LABEL: define linkonce_odr void @_ZN1SC1Ev( +// CHECK1-SAME: ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -115,50 +131,52 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@_ZN1SC2Ev -// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 { +// CHECK1-LABEL: define linkonce_odr void @_ZN1SC2Ev( +// CHECK1-SAME: ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR0]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK1-NEXT: [[I:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[I2:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK1-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: store ptr [[I2]], ptr [[I]], align 8 +// CHECK1-NEXT: [[I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK1-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK1-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr [[I3]], ptr [[I2]], align 8 // CHECK1-NEXT: store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND:%.*]] // CHECK1: for.cond: // CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4 -// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END11:%.*]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END12:%.*]] // CHECK1: for.body: // CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK1-NEXT: br label [[FOR_COND3:%.*]] -// CHECK1: for.cond3: +// CHECK1-NEXT: br label [[FOR_COND4:%.*]] +// CHECK1: for.cond4: // CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 5 -// CHECK1-NEXT: [[CMP4:%.*]] = icmp slt i32 4, [[ADD]] -// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp slt i32 4, [[ADD]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: // CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP4]], 5 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP4]], 5 // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 4, [[COND_TRUE]] ], [ [[ADD5]], [[COND_FALSE]] ] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp slt i32 [[TMP2]], [[COND]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[FOR_BODY7:%.*]], label [[FOR_END:%.*]] -// CHECK1: for.body7: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 4, [[COND_TRUE]] ], [ [[ADD6]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[CMP7:%.*]] = icmp slt i32 [[TMP2]], [[COND]] +// CHECK1-NEXT: br i1 [[CMP7]], label [[FOR_BODY8:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body8: // CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP5]], 3 -// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 7, [[MUL]] -// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[I]], align 8 -// CHECK1-NEXT: store i32 [[ADD8]], ptr [[TMP6]], align 4 -// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[I]], align 8 +// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i32 7, [[MUL]] +// CHECK1-NEXT: [[TMP6:%.*]] = load ptr, ptr [[I2]], align 8 +// CHECK1-NEXT: store i32 [[ADD9]], ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load ptr, ptr [[I2]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 // CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP8]]) // CHECK1-NEXT: br label [[FOR_INC:%.*]] @@ -166,20 +184,20 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP9]], 1 // CHECK1-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK1-NEXT: br label [[FOR_COND3]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK1-NEXT: br label [[FOR_COND4]], !llvm.loop [[LOOP3:![0-9]+]] // CHECK1: for.end: -// CHECK1-NEXT: br label [[FOR_INC9:%.*]] -// CHECK1: for.inc9: +// CHECK1-NEXT: br label [[FOR_INC10:%.*]] +// CHECK1: for.inc10: // CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP10]], 5 -// CHECK1-NEXT: store i32 [[ADD10]], ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP10]], 5 +// CHECK1-NEXT: store i32 [[ADD11]], ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] -// CHECK1: for.end11: +// CHECK1: for.end12: // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo1 -// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo1( +// CHECK1-SAME: i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 @@ -195,81 +213,83 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: store i32 [[END]], ptr [[END_ADDR]], align 4 // CHECK1-NEXT: store i32 [[STEP]], ptr [[STEP_ADDR]], align 4 // CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4 -// CHECK1-NEXT: store i32 [[TMP0]], ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[END_ADDR]], align 4 -// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_1]], align 4 -// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[STEP_ADDR]], align 4 -// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTNEW_STEP]], align 4 -// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]] +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]] // CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 -// CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP5]] // CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 -// CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP6]] +// CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]] // CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK1-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 // CHECK1-NEXT: store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND:%.*]] // CHECK1: for.cond: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK1-NEXT: [[ADD5:%.*]] = add i32 [[TMP8]], 1 -// CHECK1-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP7]], [[ADD5]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD5:%.*]] = add i32 [[TMP9]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]] // CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END17:%.*]] // CHECK1: for.body: -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: store i32 [[TMP9]], ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK1-NEXT: store i32 [[TMP10]], ptr [[DOTTILE_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND6:%.*]] // CHECK1: for.cond6: -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK1-NEXT: [[ADD7:%.*]] = add i32 [[TMP11]], 1 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP12]], 5 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD7:%.*]] = add i32 [[TMP12]], 1 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK1-NEXT: [[ADD8:%.*]] = add i32 [[TMP13]], 5 // CHECK1-NEXT: [[CMP9:%.*]] = icmp ult i32 [[ADD7]], [[ADD8]] // CHECK1-NEXT: br i1 [[CMP9]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK1-NEXT: [[ADD10:%.*]] = add i32 [[TMP13]], 1 +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK1-NEXT: [[ADD10:%.*]] = add i32 [[TMP14]], 1 // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP14]], 5 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP15]], 5 // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: // CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[ADD10]], [[COND_TRUE]] ], [ [[ADD11]], [[COND_FALSE]] ] -// CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP10]], [[COND]] +// CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP11]], [[COND]] // CHECK1-NEXT: br i1 [[CMP12]], label [[FOR_BODY13:%.*]], label [[FOR_END:%.*]] // CHECK1: for.body13: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 -// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], [[TMP17]] -// CHECK1-NEXT: [[ADD14:%.*]] = add i32 [[TMP15]], [[MUL]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: [[ADD14:%.*]] = add i32 [[TMP16]], [[MUL]] // CHECK1-NEXT: store i32 [[ADD14]], ptr [[I]], align 4 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 -// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP18]]) +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[I]], align 4 +// CHECK1-NEXT: call void (...) @body(i32 noundef [[TMP19]]) // CHECK1-NEXT: br label [[FOR_INC:%.*]] // CHECK1: for.inc: -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK1-NEXT: [[INC:%.*]] = add i32 [[TMP20]], 1 // CHECK1-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND6]], !llvm.loop [[LOOP6:![0-9]+]] // CHECK1: for.end: // CHECK1-NEXT: br label [[FOR_INC15:%.*]] // CHECK1: for.inc15: -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 5 +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add i32 [[TMP21]], 5 // CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP7:![0-9]+]] // CHECK1: for.end17: // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo2 -// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo2( +// CHECK1-SAME: i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 @@ -381,8 +401,8 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo3 -// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo3( +// CHECK1-SAME: ) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 @@ -523,8 +543,8 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo4 -// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo4( +// CHECK1-SAME: ) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 @@ -676,8 +696,8 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo5 -// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo5( +// CHECK1-SAME: ) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 @@ -885,15 +905,15 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo6 -// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo6( +// CHECK1-SAME: ) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo6.omp_outlined) // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo6.omp_outlined -// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK1-LABEL: define internal void @foo6.omp_outlined( +// CHECK1-SAME: ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -988,15 +1008,15 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@tfoo7 -// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @tfoo7( +// CHECK1-SAME: ) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: call void @_Z4foo7IiTnT_Li3ETnS0_Li5EEvS0_S0_(i32 noundef 0, i32 noundef 42) // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@_Z4foo7IiTnT_Li3ETnS0_Li5EEvS0_S0_ -// CHECK1-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR0]] comdat { +// CHECK1-LABEL: define linkonce_odr void @_Z4foo7IiTnT_Li3ETnS0_Li5EEvS0_S0_( +// CHECK1-SAME: i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR0]] comdat { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 @@ -1039,7 +1059,7 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 // CHECK1-NEXT: [[ADD7:%.*]] = add i32 [[TMP9]], 1 // CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP10]], 5 +// CHECK1-NEXT: [[ADD8:%.*]] = add i32 [[TMP10]], 5 // CHECK1-NEXT: [[CMP9:%.*]] = icmp ult i32 [[ADD7]], [[ADD8]] // CHECK1-NEXT: br i1 [[CMP9]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: @@ -1048,7 +1068,7 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: // CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP12]], 5 +// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP12]], 5 // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: // CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[ADD10]], [[COND_TRUE]] ], [ [[ADD11]], [[COND_FALSE]] ] @@ -1065,22 +1085,22 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: br label [[FOR_INC:%.*]] // CHECK1: for.inc: // CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK1-NEXT: [[INC:%.*]] = add i32 [[TMP16]], 1 // CHECK1-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND6]], !llvm.loop [[LOOP21:![0-9]+]] // CHECK1: for.end: // CHECK1-NEXT: br label [[FOR_INC15:%.*]] // CHECK1: for.inc15: // CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP17]], 5 +// CHECK1-NEXT: [[ADD16:%.*]] = add i32 [[TMP17]], 5 // CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]] // CHECK1: for.end17: // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@foo8 -// CHECK1-SAME: (i32 noundef [[A:%.*]]) #[[ATTR0]] { +// CHECK1-LABEL: define dso_local void @foo8( +// CHECK1-SAME: i32 noundef [[A:%.*]]) #[[ATTR0]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 @@ -1168,22 +1188,219 @@ extern "C" void foo8(int a) { // CHECK1-NEXT: ret void // // -// CHECK1-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_tile_codegen.cpp -// CHECK1-SAME: () #[[ATTR1]] section ".text.startup" { +// CHECK1-LABEL: define dso_local void @foo9( +// CHECK1-SAME: ptr noundef byval([[STRUCT_DATA_T:%.*]]) align 8 [[DATA:%.*]]) #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTFLOOR_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTTILE_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[V:%.*]] = alloca double, align 8 +// CHECK1-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_DATA_T]], ptr [[DATA]], i32 0, i32 0 +// CHECK1-NEXT: store ptr [[ARRAY]], ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 12 +// CHECK1-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK1-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK1-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK1-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: store i64 0, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END18:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: store i64 [[TMP8]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND7:%.*]] +// CHECK1: for.cond7: +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP10]], 1 +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP11]], 5 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i64 [[TMP12]], 1 +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[ADD12:%.*]] = add nsw i64 [[TMP13]], 5 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i64 [ [[ADD11]], [[COND_TRUE]] ], [ [[ADD12]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[CMP13:%.*]] = icmp slt i64 [[TMP9]], [[COND]] +// CHECK1-NEXT: br i1 [[CMP13]], label [[FOR_BODY14:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body14: +// CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP15]], 1 +// CHECK1-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds double, ptr [[TMP14]], i64 [[MUL]] +// CHECK1-NEXT: store ptr [[ADD_PTR15]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = load double, ptr [[TMP16]], align 8 +// CHECK1-NEXT: store double [[TMP17]], ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = load double, ptr [[V]], align 8 +// CHECK1-NEXT: call void (...) @body(double noundef [[TMP18]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i64 [[TMP19]], 1 +// CHECK1-NEXT: store i64 [[INC]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: br label [[FOR_INC16:%.*]] +// CHECK1: for.inc16: +// CHECK1-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[ADD17:%.*]] = add nsw i64 [[TMP20]], 5 +// CHECK1-NEXT: store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK1: for.end18: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define dso_local void @foo10( +// CHECK1-SAME: ptr noundef byval([[STRUCT_DATA_T:%.*]]) align 8 [[DATA:%.*]]) #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[C:%.*]] = alloca double, align 8 +// CHECK1-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTFLOOR_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTTILE_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[V:%.*]] = alloca double, align 8 +// CHECK1-NEXT: store double 4.200000e+01, ptr [[C]], align 8 +// CHECK1-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_DATA_T]], ptr [[DATA]], i32 0, i32 0 +// CHECK1-NEXT: store ptr [[ARRAY]], ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK1-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 12 +// CHECK1-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK1-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK1-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK1-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK1-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK1-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK1-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK1-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: store i64 0, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND:%.*]] +// CHECK1: for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]] +// CHECK1-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END18:%.*]] +// CHECK1: for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: store i64 [[TMP8]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND7:%.*]] +// CHECK1: for.cond7: +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP10]], 1 +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP11]], 5 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK1-NEXT: [[ADD11:%.*]] = add nsw i64 [[TMP12]], 1 +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[ADD12:%.*]] = add nsw i64 [[TMP13]], 5 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i64 [ [[ADD11]], [[COND_TRUE]] ], [ [[ADD12]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[CMP13:%.*]] = icmp slt i64 [[TMP9]], [[COND]] +// CHECK1-NEXT: br i1 [[CMP13]], label [[FOR_BODY14:%.*]], label [[FOR_END:%.*]] +// CHECK1: for.body14: +// CHECK1-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP15]], 1 +// CHECK1-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds double, ptr [[TMP14]], i64 [[MUL]] +// CHECK1-NEXT: store ptr [[ADD_PTR15]], ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = load double, ptr [[TMP16]], align 8 +// CHECK1-NEXT: store double [[TMP17]], ptr [[V]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = load double, ptr [[C]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = load double, ptr [[V]], align 8 +// CHECK1-NEXT: call void (...) @body(double noundef [[TMP18]], double noundef [[TMP19]]) +// CHECK1-NEXT: br label [[FOR_INC:%.*]] +// CHECK1: for.inc: +// CHECK1-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[INC:%.*]] = add nsw i64 [[TMP20]], 1 +// CHECK1-NEXT: store i64 [[INC]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK1: for.end: +// CHECK1-NEXT: br label [[FOR_INC16:%.*]] +// CHECK1: for.inc16: +// CHECK1-NEXT: [[TMP21:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: [[ADD17:%.*]] = add nsw i64 [[TMP21]], 5 +// CHECK1-NEXT: store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK1-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK1: for.end18: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define internal void @_GLOBAL__sub_I_tile_codegen.cpp( +// CHECK1-SAME: ) #[[ATTR1]] section ".text.startup" { // CHECK1-NEXT: entry: // CHECK1-NEXT: call void @__cxx_global_var_init() // CHECK1-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@__cxx_global_var_init -// CHECK2-SAME: () #[[ATTR0:[0-9]+]] section ".text.startup" { +// CHECK2-LABEL: define internal void @__cxx_global_var_init( +// CHECK2-SAME: ) #[[ATTR0:[0-9]+]] section ".text.startup" { // CHECK2-NEXT: entry: // CHECK2-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @s) // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC1Ev -// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 { +// CHECK2-LABEL: define linkonce_odr void @_ZN1SC1Ev( +// CHECK2-SAME: ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -1192,50 +1409,52 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@_ZN1SC2Ev -// CHECK2-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 { +// CHECK2-LABEL: define linkonce_odr void @_ZN1SC2Ev( +// CHECK2-SAME: ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 -// CHECK2-NEXT: [[I:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[I2:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTFLOOR_0_IV_I:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTTILE_0_IV_I:%.*]] = alloca i32, align 4 // CHECK2-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 -// CHECK2-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: store ptr [[I2]], ptr [[I]], align 8 +// CHECK2-NEXT: [[I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK2-NEXT: store i32 7, ptr [[I]], align 4 +// CHECK2-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK2-NEXT: store ptr [[I3]], ptr [[I2]], align 8 // CHECK2-NEXT: store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: br label [[FOR_COND:%.*]] // CHECK2: for.cond: // CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 4 -// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END11:%.*]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END12:%.*]] // CHECK2: for.body: // CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: store i32 [[TMP1]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND3:%.*]] -// CHECK2: for.cond3: +// CHECK2-NEXT: br label [[FOR_COND4:%.*]] +// CHECK2: for.cond4: // CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 5 -// CHECK2-NEXT: [[CMP4:%.*]] = icmp slt i32 4, [[ADD]] -// CHECK2-NEXT: br i1 [[CMP4]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2-NEXT: [[CMP5:%.*]] = icmp slt i32 4, [[ADD]] +// CHECK2-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: // CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP4]], 5 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP4]], 5 // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: -// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 4, [[COND_TRUE]] ], [ [[ADD5]], [[COND_FALSE]] ] -// CHECK2-NEXT: [[CMP6:%.*]] = icmp slt i32 [[TMP2]], [[COND]] -// CHECK2-NEXT: br i1 [[CMP6]], label [[FOR_BODY7:%.*]], label [[FOR_END:%.*]] -// CHECK2: for.body7: +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 4, [[COND_TRUE]] ], [ [[ADD6]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[CMP7:%.*]] = icmp slt i32 [[TMP2]], [[COND]] +// CHECK2-NEXT: br i1 [[CMP7]], label [[FOR_BODY8:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body8: // CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP5]], 3 -// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 7, [[MUL]] -// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[I]], align 8 -// CHECK2-NEXT: store i32 [[ADD8]], ptr [[TMP6]], align 4 -// CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[I]], align 8 +// CHECK2-NEXT: [[ADD9:%.*]] = add nsw i32 7, [[MUL]] +// CHECK2-NEXT: [[TMP6:%.*]] = load ptr, ptr [[I2]], align 8 +// CHECK2-NEXT: store i32 [[ADD9]], ptr [[TMP6]], align 4 +// CHECK2-NEXT: [[TMP7:%.*]] = load ptr, ptr [[I2]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4 // CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP8]]) // CHECK2-NEXT: br label [[FOR_INC:%.*]] @@ -1243,26 +1462,26 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP9]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND3]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND4]], !llvm.loop [[LOOP3:![0-9]+]] // CHECK2: for.end: -// CHECK2-NEXT: br label [[FOR_INC9:%.*]] -// CHECK2: for.inc9: +// CHECK2-NEXT: br label [[FOR_INC10:%.*]] +// CHECK2: for.inc10: // CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD10:%.*]] = add nsw i32 [[TMP10]], 5 -// CHECK2-NEXT: store i32 [[ADD10]], ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP10]], 5 +// CHECK2-NEXT: store i32 [[ADD11]], ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]] -// CHECK2: for.end11: +// CHECK2: for.end12: // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@body -// CHECK2-SAME: (...) #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @body( +// CHECK2-SAME: ...) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo1 -// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo1( +// CHECK2-SAME: i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 @@ -1278,81 +1497,183 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: store i32 [[END]], ptr [[END_ADDR]], align 4 // CHECK2-NEXT: store i32 [[STEP]], ptr [[STEP_ADDR]], align 4 // CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[START_ADDR]], align 4 -// CHECK2-NEXT: store i32 [[TMP0]], ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[END_ADDR]], align 4 -// CHECK2-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_1]], align 4 -// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[STEP_ADDR]], align 4 -// CHECK2-NEXT: store i32 [[TMP2]], ptr [[DOTNEW_STEP]], align 4 -// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 -// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP3]], [[TMP4]] +// CHECK2-NEXT: store i32 [[TMP0]], ptr [[I]], align 4 +// CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[START_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP1]], ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[END_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP2]], ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[STEP_ADDR]], align 4 +// CHECK2-NEXT: store i32 [[TMP3]], ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], [[TMP5]] // CHECK2-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 -// CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 -// CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP5]] // CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 -// CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP6]] +// CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], [[TMP6]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], [[TMP7]] // CHECK2-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK2-NEXT: store i32 [[SUB4]], ptr [[DOTCAPTURE_EXPR_2]], align 4 // CHECK2-NEXT: store i32 0, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: br label [[FOR_COND:%.*]] // CHECK2: for.cond: -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK2-NEXT: [[ADD5:%.*]] = add i32 [[TMP8]], 1 -// CHECK2-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP7]], [[ADD5]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD5:%.*]] = add i32 [[TMP9]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP8]], [[ADD5]] // CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END17:%.*]] // CHECK2: for.body: -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: store i32 [[TMP9]], ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK2-NEXT: store i32 [[TMP10]], ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: br label [[FOR_COND6:%.*]] // CHECK2: for.cond6: -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK2-NEXT: [[ADD7:%.*]] = add i32 [[TMP11]], 1 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP12]], 5 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD7:%.*]] = add i32 [[TMP12]], 1 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK2-NEXT: [[ADD8:%.*]] = add i32 [[TMP13]], 5 // CHECK2-NEXT: [[CMP9:%.*]] = icmp ult i32 [[ADD7]], [[ADD8]] // CHECK2-NEXT: br i1 [[CMP9]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: -// CHECK2-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 -// CHECK2-NEXT: [[ADD10:%.*]] = add i32 [[TMP13]], 1 +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 +// CHECK2-NEXT: [[ADD10:%.*]] = add i32 [[TMP14]], 1 // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: -// CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP14]], 5 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[TMP15]], 5 // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: // CHECK2-NEXT: [[COND:%.*]] = phi i32 [ [[ADD10]], [[COND_TRUE]] ], [ [[ADD11]], [[COND_FALSE]] ] -// CHECK2-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP10]], [[COND]] +// CHECK2-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP11]], [[COND]] // CHECK2-NEXT: br i1 [[CMP12]], label [[FOR_BODY13:%.*]], label [[FOR_END:%.*]] // CHECK2: for.body13: -// CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 -// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 -// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], [[TMP17]] -// CHECK2-NEXT: [[ADD14:%.*]] = add i32 [[TMP15]], [[MUL]] +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4 +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTNEW_STEP]], align 4 +// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP17]], [[TMP18]] +// CHECK2-NEXT: [[ADD14:%.*]] = add i32 [[TMP16]], [[MUL]] // CHECK2-NEXT: store i32 [[ADD14]], ptr [[I]], align 4 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32, ptr [[I]], align 4 -// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP18]]) +// CHECK2-NEXT: [[TMP19:%.*]] = load i32, ptr [[I]], align 4 +// CHECK2-NEXT: call void (...) @body(i32 noundef [[TMP19]]) // CHECK2-NEXT: br label [[FOR_INC:%.*]] // CHECK2: for.inc: -// CHECK2-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 +// CHECK2-NEXT: [[INC:%.*]] = add i32 [[TMP20]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: br label [[FOR_COND6]], !llvm.loop [[LOOP6:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[FOR_INC15:%.*]] // CHECK2: for.inc15: -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 5 +// CHECK2-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 +// CHECK2-NEXT: [[ADD16:%.*]] = add i32 [[TMP21]], 5 // CHECK2-NEXT: store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP7:![0-9]+]] // CHECK2: for.end17: // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo2 -// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo10( +// CHECK2-SAME: ptr noundef byval([[STRUCT_DATA_T:%.*]]) align 8 [[DATA:%.*]]) #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[C:%.*]] = alloca double, align 8 +// CHECK2-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTFLOOR_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTTILE_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[V:%.*]] = alloca double, align 8 +// CHECK2-NEXT: store double 4.200000e+01, ptr [[C]], align 8 +// CHECK2-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_DATA_T]], ptr [[DATA]], i32 0, i32 0 +// CHECK2-NEXT: store ptr [[ARRAY]], ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 12 +// CHECK2-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK2-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK2-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK2-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK2-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: store i64 0, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END18:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: store i64 [[TMP8]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND7:%.*]] +// CHECK2: for.cond7: +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP10]], 1 +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP11]], 5 +// CHECK2-NEXT: [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]] +// CHECK2-NEXT: br i1 [[CMP10]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD11:%.*]] = add nsw i64 [[TMP12]], 1 +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[ADD12:%.*]] = add nsw i64 [[TMP13]], 5 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i64 [ [[ADD11]], [[COND_TRUE]] ], [ [[ADD12]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[CMP13:%.*]] = icmp slt i64 [[TMP9]], [[COND]] +// CHECK2-NEXT: br i1 [[CMP13]], label [[FOR_BODY14:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body14: +// CHECK2-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP15]], 1 +// CHECK2-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds double, ptr [[TMP14]], i64 [[MUL]] +// CHECK2-NEXT: store ptr [[ADD_PTR15]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP16:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP17:%.*]] = load double, ptr [[TMP16]], align 8 +// CHECK2-NEXT: store double [[TMP17]], ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP18:%.*]] = load double, ptr [[C]], align 8 +// CHECK2-NEXT: [[TMP19:%.*]] = load double, ptr [[V]], align 8 +// CHECK2-NEXT: call void (...) @body(double noundef [[TMP18]], double noundef [[TMP19]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i64 [[TMP20]], 1 +// CHECK2-NEXT: store i64 [[INC]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP8:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: br label [[FOR_INC16:%.*]] +// CHECK2: for.inc16: +// CHECK2-NEXT: [[TMP21:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[ADD17:%.*]] = add nsw i64 [[TMP21]], 5 +// CHECK2-NEXT: store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK2: for.end18: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define dso_local void @foo2( +// CHECK2-SAME: i32 noundef [[START:%.*]], i32 noundef [[END:%.*]], i32 noundef [[STEP:%.*]]) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 @@ -1438,34 +1759,34 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4 // CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP14]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], align 4 -// CHECK2-NEXT: br label [[FOR_COND10]], !llvm.loop [[LOOP8:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND10]], !llvm.loop [[LOOP10:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[FOR_INC22:%.*]] // CHECK2: for.inc22: // CHECK2-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[INC23:%.*]] = add nsw i32 [[TMP15]], 1 // CHECK2-NEXT: store i32 [[INC23]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND4]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND4]], !llvm.loop [[LOOP11:![0-9]+]] // CHECK2: for.end24: // CHECK2-NEXT: br label [[FOR_INC25:%.*]] // CHECK2: for.inc25: // CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4 // CHECK2-NEXT: [[ADD26:%.*]] = add nsw i32 [[TMP16]], 5 // CHECK2-NEXT: store i32 [[ADD26]], ptr [[DOTFLOOR_1_IV_J]], align 4 -// CHECK2-NEXT: br label [[FOR_COND1]], !llvm.loop [[LOOP10:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND1]], !llvm.loop [[LOOP12:![0-9]+]] // CHECK2: for.end27: // CHECK2-NEXT: br label [[FOR_INC28:%.*]] // CHECK2: for.inc28: // CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP17]], 5 // CHECK2-NEXT: store i32 [[ADD29]], ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP13:![0-9]+]] // CHECK2: for.end30: // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo3 -// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo3( +// CHECK2-SAME: ) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 @@ -1574,21 +1895,21 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4 // CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP20]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], align 4 -// CHECK2-NEXT: br label [[FOR_COND15]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND15]], !llvm.loop [[LOOP14:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[FOR_INC27:%.*]] // CHECK2: for.inc27: // CHECK2-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[INC28:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK2-NEXT: store i32 [[INC28]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND3]], !llvm.loop [[LOOP13:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND3]], !llvm.loop [[LOOP15:![0-9]+]] // CHECK2: for.end29: // CHECK2-NEXT: br label [[FOR_INC30:%.*]] // CHECK2: for.inc30: // CHECK2-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4 // CHECK2-NEXT: [[ADD31:%.*]] = add nsw i32 [[TMP22]], 5 // CHECK2-NEXT: store i32 [[ADD31]], ptr [[DOTFLOOR_1_IV_J]], align 4 -// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP14:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK2: for.end32: // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -1606,8 +1927,8 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo4 -// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo4( +// CHECK2-SAME: ) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 @@ -1727,21 +2048,21 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTTILE_1_IV_J]], align 4 // CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP22]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_1_IV_J]], align 4 -// CHECK2-NEXT: br label [[FOR_COND20]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND20]], !llvm.loop [[LOOP17:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[FOR_INC32:%.*]] // CHECK2: for.inc32: // CHECK2-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[INC33:%.*]] = add nsw i32 [[TMP23]], 1 // CHECK2-NEXT: store i32 [[INC33]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND8]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND8]], !llvm.loop [[LOOP18:![0-9]+]] // CHECK2: for.end34: // CHECK2-NEXT: br label [[FOR_INC35:%.*]] // CHECK2: for.inc35: // CHECK2-NEXT: [[TMP24:%.*]] = load i32, ptr [[DOTFLOOR_1_IV_J]], align 4 // CHECK2-NEXT: [[ADD36:%.*]] = add nsw i32 [[TMP24]], 5 // CHECK2-NEXT: store i32 [[ADD36]], ptr [[DOTFLOOR_1_IV_J]], align 4 -// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP19:![0-9]+]] // CHECK2: for.end37: // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -1759,8 +2080,8 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo5 -// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo5( +// CHECK2-SAME: ) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTOMP_IV:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[TMP:%.*]] = alloca i32, align 4 @@ -1968,15 +2289,15 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo6 -// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo6( +// CHECK2-SAME: ) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo6.omp_outlined) // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo6.omp_outlined -// CHECK2-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK2-LABEL: define internal void @foo6.omp_outlined( +// CHECK2-SAME: ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 @@ -2054,7 +2375,7 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP14]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP18:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP20:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: @@ -2071,8 +2392,8 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@foo8 -// CHECK2-SAME: (i32 noundef [[A:%.*]]) #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo8( +// CHECK2-SAME: i32 noundef [[A:%.*]]) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 @@ -2138,7 +2459,7 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 // CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP11]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND1]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND1]], !llvm.loop [[LOOP23:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[FOR_INC17:%.*]] // CHECK2: for.inc17: @@ -2155,20 +2476,117 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 // CHECK2-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP14]], [[COND22]] // CHECK2-NEXT: store i32 [[ADD23]], ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] // CHECK2: for.end24: // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@tfoo7 -// CHECK2-SAME: () #[[ATTR1]] { +// CHECK2-LABEL: define dso_local void @foo9( +// CHECK2-SAME: ptr noundef byval([[STRUCT_DATA_T:%.*]]) align 8 [[DATA:%.*]]) #[[ATTR1]] { +// CHECK2-NEXT: entry: +// CHECK2-NEXT: [[__RANGE2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__END2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[__BEGIN2:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_3:%.*]] = alloca ptr, align 8 +// CHECK2-NEXT: [[DOTCAPTURE_EXPR_4:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTFLOOR_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[DOTTILE_0_IV___BEGIN2:%.*]] = alloca i64, align 8 +// CHECK2-NEXT: [[V:%.*]] = alloca double, align 8 +// CHECK2-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_DATA_T]], ptr [[DATA]], i32 0, i32 0 +// CHECK2-NEXT: store ptr [[ARRAY]], ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP0]], i64 0, i64 0 +// CHECK2-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[ARRAYDECAY]], i64 12 +// CHECK2-NEXT: store ptr [[ADD_PTR]], ptr [[__END2]], align 8 +// CHECK2-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP1]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY1]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[__RANGE2]], align 8 +// CHECK2-NEXT: [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x double], ptr [[TMP2]], i64 0, i64 0 +// CHECK2-NEXT: store ptr [[ARRAYDECAY2]], ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP3:%.*]] = load ptr, ptr [[__END2]], align 8 +// CHECK2-NEXT: store ptr [[TMP3]], ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_3]], align 8 +// CHECK2-NEXT: [[TMP5:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[TMP4]] to i64 +// CHECK2-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[TMP5]] to i64 +// CHECK2-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]] +// CHECK2-NEXT: [[SUB_PTR_DIV:%.*]] = sdiv exact i64 [[SUB_PTR_SUB]], 8 +// CHECK2-NEXT: [[SUB:%.*]] = sub nsw i64 [[SUB_PTR_DIV]], 1 +// CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[SUB]], 1 +// CHECK2-NEXT: [[DIV:%.*]] = sdiv i64 [[ADD]], 1 +// CHECK2-NEXT: [[SUB5:%.*]] = sub nsw i64 [[DIV]], 1 +// CHECK2-NEXT: store i64 [[SUB5]], ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: store i64 0, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND:%.*]] +// CHECK2: for.cond: +// CHECK2-NEXT: [[TMP6:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP7:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i64 [[TMP7]], 1 +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i64 [[TMP6]], [[ADD6]] +// CHECK2-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END18:%.*]] +// CHECK2: for.body: +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: store i64 [[TMP8]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND7:%.*]] +// CHECK2: for.cond7: +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP10:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP10]], 1 +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[ADD9:%.*]] = add nsw i64 [[TMP11]], 5 +// CHECK2-NEXT: [[CMP10:%.*]] = icmp slt i64 [[ADD8]], [[ADD9]] +// CHECK2-NEXT: br i1 [[CMP10]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK2: cond.true: +// CHECK2-NEXT: [[TMP12:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR_4]], align 8 +// CHECK2-NEXT: [[ADD11:%.*]] = add nsw i64 [[TMP12]], 1 +// CHECK2-NEXT: br label [[COND_END:%.*]] +// CHECK2: cond.false: +// CHECK2-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[ADD12:%.*]] = add nsw i64 [[TMP13]], 5 +// CHECK2-NEXT: br label [[COND_END]] +// CHECK2: cond.end: +// CHECK2-NEXT: [[COND:%.*]] = phi i64 [ [[ADD11]], [[COND_TRUE]] ], [ [[ADD12]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[CMP13:%.*]] = icmp slt i64 [[TMP9]], [[COND]] +// CHECK2-NEXT: br i1 [[CMP13]], label [[FOR_BODY14:%.*]], label [[FOR_END:%.*]] +// CHECK2: for.body14: +// CHECK2-NEXT: [[TMP14:%.*]] = load ptr, ptr [[DOTCAPTURE_EXPR_]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP15]], 1 +// CHECK2-NEXT: [[ADD_PTR15:%.*]] = getelementptr inbounds double, ptr [[TMP14]], i64 [[MUL]] +// CHECK2-NEXT: store ptr [[ADD_PTR15]], ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP16:%.*]] = load ptr, ptr [[__BEGIN2]], align 8 +// CHECK2-NEXT: [[TMP17:%.*]] = load double, ptr [[TMP16]], align 8 +// CHECK2-NEXT: store double [[TMP17]], ptr [[V]], align 8 +// CHECK2-NEXT: [[TMP18:%.*]] = load double, ptr [[V]], align 8 +// CHECK2-NEXT: call void (...) @body(double noundef [[TMP18]]) +// CHECK2-NEXT: br label [[FOR_INC:%.*]] +// CHECK2: for.inc: +// CHECK2-NEXT: [[TMP19:%.*]] = load i64, ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[INC:%.*]] = add nsw i64 [[TMP19]], 1 +// CHECK2-NEXT: store i64 [[INC]], ptr [[DOTTILE_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND7]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK2: for.end: +// CHECK2-NEXT: br label [[FOR_INC16:%.*]] +// CHECK2: for.inc16: +// CHECK2-NEXT: [[TMP20:%.*]] = load i64, ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: [[ADD17:%.*]] = add nsw i64 [[TMP20]], 5 +// CHECK2-NEXT: store i64 [[ADD17]], ptr [[DOTFLOOR_0_IV___BEGIN2]], align 8 +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK2: for.end18: +// CHECK2-NEXT: ret void +// +// +// CHECK2-LABEL: define dso_local void @tfoo7( +// CHECK2-SAME: ) #[[ATTR1]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: call void @_Z4foo7IiTnT_Li3ETnS0_Li5EEvS0_S0_(i32 noundef 0, i32 noundef 42) // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@_Z4foo7IiTnT_Li3ETnS0_Li5EEvS0_S0_ -// CHECK2-SAME: (i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR1]] comdat { +// CHECK2-LABEL: define linkonce_odr void @_Z4foo7IiTnT_Li3ETnS0_Li5EEvS0_S0_( +// CHECK2-SAME: i32 noundef [[START:%.*]], i32 noundef [[END:%.*]]) #[[ATTR1]] comdat { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[START_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[END_ADDR:%.*]] = alloca i32, align 4 @@ -2211,7 +2629,7 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_2]], align 4 // CHECK2-NEXT: [[ADD7:%.*]] = add i32 [[TMP9]], 1 // CHECK2-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP10]], 5 +// CHECK2-NEXT: [[ADD8:%.*]] = add i32 [[TMP10]], 5 // CHECK2-NEXT: [[CMP9:%.*]] = icmp ult i32 [[ADD7]], [[ADD8]] // CHECK2-NEXT: br i1 [[CMP9]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: @@ -2220,7 +2638,7 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: // CHECK2-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD11:%.*]] = add nsw i32 [[TMP12]], 5 +// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[TMP12]], 5 // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: // CHECK2-NEXT: [[COND:%.*]] = phi i32 [ [[ADD10]], [[COND_TRUE]] ], [ [[ADD11]], [[COND_FALSE]] ] @@ -2237,23 +2655,74 @@ extern "C" void foo8(int a) { // CHECK2-NEXT: br label [[FOR_INC:%.*]] // CHECK2: for.inc: // CHECK2-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK2-NEXT: [[INC:%.*]] = add i32 [[TMP16]], 1 // CHECK2-NEXT: store i32 [[INC]], ptr [[DOTTILE_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND6]], !llvm.loop [[LOOP23:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND6]], !llvm.loop [[LOOP27:![0-9]+]] // CHECK2: for.end: // CHECK2-NEXT: br label [[FOR_INC15:%.*]] // CHECK2: for.inc15: // CHECK2-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP17]], 5 +// CHECK2-NEXT: [[ADD16:%.*]] = add i32 [[TMP17]], 5 // CHECK2-NEXT: store i32 [[ADD16]], ptr [[DOTFLOOR_0_IV_I]], align 4 -// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK2-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] // CHECK2: for.end17: // CHECK2-NEXT: ret void // // -// CHECK2-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_tile_codegen.cpp -// CHECK2-SAME: () #[[ATTR0]] section ".text.startup" { +// CHECK2-LABEL: define internal void @_GLOBAL__sub_I_tile_codegen.cpp( +// CHECK2-SAME: ) #[[ATTR0]] section ".text.startup" { // CHECK2-NEXT: entry: // CHECK2-NEXT: call void @__cxx_global_var_init() // CHECK2-NEXT: ret void // +//. +// CHECK1: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]]} +// CHECK1: [[META4]] = !{!"llvm.loop.mustprogress"} +// CHECK1: [[LOOP5]] = distinct !{[[LOOP5]], [[META4]]} +// CHECK1: [[LOOP6]] = distinct !{[[LOOP6]], [[META4]]} +// CHECK1: [[LOOP7]] = distinct !{[[LOOP7]], [[META4]]} +// CHECK1: [[LOOP8]] = distinct !{[[LOOP8]], [[META4]]} +// CHECK1: [[LOOP9]] = distinct !{[[LOOP9]], [[META4]]} +// CHECK1: [[LOOP10]] = distinct !{[[LOOP10]], [[META4]]} +// CHECK1: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]]} +// CHECK1: [[LOOP12]] = distinct !{[[LOOP12]], [[META4]]} +// CHECK1: [[LOOP13]] = distinct !{[[LOOP13]], [[META4]]} +// CHECK1: [[LOOP14]] = distinct !{[[LOOP14]], [[META4]]} +// CHECK1: [[LOOP15]] = distinct !{[[LOOP15]], [[META4]]} +// CHECK1: [[LOOP16]] = distinct !{[[LOOP16]], [[META4]]} +// CHECK1: [[LOOP17]] = distinct !{[[LOOP17]], [[META4]]} +// CHECK1: [[LOOP18]] = distinct !{[[LOOP18]], [[META4]]} +// CHECK1: [[LOOP21]] = distinct !{[[LOOP21]], [[META4]]} +// CHECK1: [[LOOP22]] = distinct !{[[LOOP22]], [[META4]]} +// CHECK1: [[LOOP23]] = distinct !{[[LOOP23]], [[META4]]} +// CHECK1: [[LOOP24]] = distinct !{[[LOOP24]], [[META4]]} +// CHECK1: [[LOOP25]] = distinct !{[[LOOP25]], [[META4]]} +// CHECK1: [[LOOP26]] = distinct !{[[LOOP26]], [[META4]]} +// CHECK1: [[LOOP27]] = distinct !{[[LOOP27]], [[META4]]} +// CHECK1: [[LOOP28]] = distinct !{[[LOOP28]], [[META4]]} +//. +// CHECK2: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]]} +// CHECK2: [[META4]] = !{!"llvm.loop.mustprogress"} +// CHECK2: [[LOOP5]] = distinct !{[[LOOP5]], [[META4]]} +// CHECK2: [[LOOP6]] = distinct !{[[LOOP6]], [[META4]]} +// CHECK2: [[LOOP7]] = distinct !{[[LOOP7]], [[META4]]} +// CHECK2: [[LOOP8]] = distinct !{[[LOOP8]], [[META4]]} +// CHECK2: [[LOOP9]] = distinct !{[[LOOP9]], [[META4]]} +// CHECK2: [[LOOP10]] = distinct !{[[LOOP10]], [[META4]]} +// CHECK2: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]]} +// CHECK2: [[LOOP12]] = distinct !{[[LOOP12]], [[META4]]} +// CHECK2: [[LOOP13]] = distinct !{[[LOOP13]], [[META4]]} +// CHECK2: [[LOOP14]] = distinct !{[[LOOP14]], [[META4]]} +// CHECK2: [[LOOP15]] = distinct !{[[LOOP15]], [[META4]]} +// CHECK2: [[LOOP16]] = distinct !{[[LOOP16]], [[META4]]} +// CHECK2: [[LOOP17]] = distinct !{[[LOOP17]], [[META4]]} +// CHECK2: [[LOOP18]] = distinct !{[[LOOP18]], [[META4]]} +// CHECK2: [[LOOP19]] = distinct !{[[LOOP19]], [[META4]]} +// CHECK2: [[LOOP20]] = distinct !{[[LOOP20]], [[META4]]} +// CHECK2: [[LOOP23]] = distinct !{[[LOOP23]], [[META4]]} +// CHECK2: [[LOOP24]] = distinct !{[[LOOP24]], [[META4]]} +// CHECK2: [[LOOP25]] = distinct !{[[LOOP25]], [[META4]]} +// CHECK2: [[LOOP26]] = distinct !{[[LOOP26]], [[META4]]} +// CHECK2: [[LOOP27]] = distinct !{[[LOOP27]], [[META4]]} +// CHECK2: [[LOOP28]] = distinct !{[[LOOP28]], [[META4]]} +//. diff --git a/clang/test/OpenMP/tile_codegen_for_dependent.cpp b/clang/test/OpenMP/tile_codegen_for_dependent.cpp index 93c51c9165a47..820d33d15287b 100644 --- a/clang/test/OpenMP/tile_codegen_for_dependent.cpp +++ b/clang/test/OpenMP/tile_codegen_for_dependent.cpp @@ -17,7 +17,7 @@ extern "C" void body(...) {} -// IR-LABEL: @func( +// IR-LABEL: define {{.*}}@func( // IR-NEXT: [[ENTRY:.*]]: // IR-NEXT: %[[START_ADDR:.+]] = alloca i32, align 4 // IR-NEXT: %[[END_ADDR:.+]] = alloca i32, align 4 @@ -27,18 +27,18 @@ extern "C" void body(...) {} // IR-NEXT: %[[I:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTCAPTURE_EXPR_:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTCAPTURE_EXPR_1:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTNEW_STEP:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTCAPTURE_EXPR_2:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_3:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_6:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_8:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTCAPTURE_EXPR_5:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTCAPTURE_EXPR_7:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTFLOOR_0_IV_I:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_LB:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_UB:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_STRIDE:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_IS_LAST:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTFLOOR_0_IV_I12:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTFLOOR_0_IV_I11:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTTILE_0_IV_I:.+]] = alloca i32, align 4 -// IR-NEXT: %[[TMP0:.+]] = call i32 @__kmpc_global_thread_num(ptr @2) +// IR-NEXT: %[[TMP0:.+]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:.+]]) // IR-NEXT: store i32 %[[START:.+]], ptr %[[START_ADDR]], align 4 // IR-NEXT: store i32 %[[END:.+]], ptr %[[END_ADDR]], align 4 // IR-NEXT: store i32 %[[STEP:.+]], ptr %[[STEP_ADDR]], align 4 @@ -49,44 +49,44 @@ extern "C" void body(...) {} // IR-NEXT: %[[TMP3:.+]] = load i32, ptr %[[END_ADDR]], align 4 // IR-NEXT: store i32 %[[TMP3]], ptr %[[DOTCAPTURE_EXPR_1]], align 4 // IR-NEXT: %[[TMP4:.+]] = load i32, ptr %[[STEP_ADDR]], align 4 -// IR-NEXT: store i32 %[[TMP4]], ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: store i32 %[[TMP4]], ptr %[[DOTNEW_STEP]], align 4 // IR-NEXT: %[[TMP5:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_1]], align 4 // IR-NEXT: %[[TMP6:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_]], align 4 // IR-NEXT: %[[SUB:.+]] = sub i32 %[[TMP5]], %[[TMP6]] -// IR-NEXT: %[[SUB4:.+]] = sub i32 %[[SUB]], 1 -// IR-NEXT: %[[TMP7:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 -// IR-NEXT: %[[ADD:.+]] = add i32 %[[SUB4]], %[[TMP7]] -// IR-NEXT: %[[TMP8:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[SUB3:.+]] = sub i32 %[[SUB]], 1 +// IR-NEXT: %[[TMP7:.+]] = load i32, ptr %[[DOTNEW_STEP]], align 4 +// IR-NEXT: %[[ADD:.+]] = add i32 %[[SUB3]], %[[TMP7]] +// IR-NEXT: %[[TMP8:.+]] = load i32, ptr %[[DOTNEW_STEP]], align 4 // IR-NEXT: %[[DIV:.+]] = udiv i32 %[[ADD]], %[[TMP8]] -// IR-NEXT: %[[SUB5:.+]] = sub i32 %[[DIV]], 1 -// IR-NEXT: store i32 %[[SUB5]], ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[TMP9:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[ADD7:.+]] = add i32 %[[TMP9]], 1 -// IR-NEXT: store i32 %[[ADD7]], ptr %[[DOTCAPTURE_EXPR_6]], align 4 -// IR-NEXT: %[[TMP10:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_6]], align 4 -// IR-NEXT: %[[SUB9:.+]] = sub i32 %[[TMP10]], -3 -// IR-NEXT: %[[DIV10:.+]] = udiv i32 %[[SUB9]], 4 -// IR-NEXT: %[[SUB11:.+]] = sub i32 %[[DIV10]], 1 -// IR-NEXT: store i32 %[[SUB11]], ptr %[[DOTCAPTURE_EXPR_8]], align 4 +// IR-NEXT: %[[SUB4:.+]] = sub i32 %[[DIV]], 1 +// IR-NEXT: store i32 %[[SUB4]], ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[TMP9:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[ADD6:.+]] = add i32 %[[TMP9]], 1 +// IR-NEXT: store i32 %[[ADD6]], ptr %[[DOTCAPTURE_EXPR_5]], align 4 +// IR-NEXT: %[[TMP10:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_5]], align 4 +// IR-NEXT: %[[SUB8:.+]] = sub i32 %[[TMP10]], -3 +// IR-NEXT: %[[DIV9:.+]] = udiv i32 %[[SUB8]], 4 +// IR-NEXT: %[[SUB10:.+]] = sub i32 %[[DIV9]], 1 +// IR-NEXT: store i32 %[[SUB10]], ptr %[[DOTCAPTURE_EXPR_7]], align 4 // IR-NEXT: store i32 0, ptr %[[DOTFLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[TMP11:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_6]], align 4 +// IR-NEXT: %[[TMP11:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_5]], align 4 // IR-NEXT: %[[CMP:.+]] = icmp ult i32 0, %[[TMP11]] // IR-NEXT: br i1 %[[CMP]], label %[[OMP_PRECOND_THEN:.+]], label %[[OMP_PRECOND_END:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_PRECOND_THEN]]: // IR-NEXT: store i32 0, ptr %[[DOTOMP_LB]], align 4 -// IR-NEXT: %[[TMP12:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_8]], align 4 +// IR-NEXT: %[[TMP12:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_7]], align 4 // IR-NEXT: store i32 %[[TMP12]], ptr %[[DOTOMP_UB]], align 4 // IR-NEXT: store i32 1, ptr %[[DOTOMP_STRIDE]], align 4 // IR-NEXT: store i32 0, ptr %[[DOTOMP_IS_LAST]], align 4 -// IR-NEXT: call void @__kmpc_for_static_init_4u(ptr @1, i32 %[[TMP0]], i32 34, ptr %[[DOTOMP_IS_LAST]], ptr %[[DOTOMP_LB]], ptr %[[DOTOMP_UB]], ptr %[[DOTOMP_STRIDE]], i32 1, i32 1) +// IR-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1:.+]], i32 %[[TMP0]], i32 34, ptr %[[DOTOMP_IS_LAST]], ptr %[[DOTOMP_LB]], ptr %[[DOTOMP_UB]], ptr %[[DOTOMP_STRIDE]], i32 1, i32 1) // IR-NEXT: %[[TMP13:.+]] = load i32, ptr %[[DOTOMP_UB]], align 4 -// IR-NEXT: %[[TMP14:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_8]], align 4 -// IR-NEXT: %[[CMP13:.+]] = icmp ugt i32 %[[TMP13]], %[[TMP14]] -// IR-NEXT: br i1 %[[CMP13]], label %[[COND_TRUE:.+]], label %[[COND_FALSE:.+]] +// IR-NEXT: %[[TMP14:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_7]], align 4 +// IR-NEXT: %[[CMP12:.+]] = icmp ugt i32 %[[TMP13]], %[[TMP14]] +// IR-NEXT: br i1 %[[CMP12]], label %[[COND_TRUE:.+]], label %[[COND_FALSE:.+]] // IR-EMPTY: // IR-NEXT: [[COND_TRUE]]: -// IR-NEXT: %[[TMP15:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_8]], align 4 +// IR-NEXT: %[[TMP15:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_7]], align 4 // IR-NEXT: br label %[[COND_END:.+]] // IR-EMPTY: // IR-NEXT: [[COND_FALSE]]: @@ -103,50 +103,50 @@ extern "C" void body(...) {} // IR-NEXT: [[OMP_INNER_FOR_COND]]: // IR-NEXT: %[[TMP18:.+]] = load i32, ptr %[[DOTOMP_IV]], align 4 // IR-NEXT: %[[TMP19:.+]] = load i32, ptr %[[DOTOMP_UB]], align 4 -// IR-NEXT: %[[ADD14:.+]] = add i32 %[[TMP19]], 1 -// IR-NEXT: %[[CMP15:.+]] = icmp ult i32 %[[TMP18]], %[[ADD14]] -// IR-NEXT: br i1 %[[CMP15]], label %[[OMP_INNER_FOR_BODY:.+]], label %[[OMP_INNER_FOR_END:.+]] +// IR-NEXT: %[[ADD13:.+]] = add i32 %[[TMP19]], 1 +// IR-NEXT: %[[CMP14:.+]] = icmp ult i32 %[[TMP18]], %[[ADD13]] +// IR-NEXT: br i1 %[[CMP14]], label %[[OMP_INNER_FOR_BODY:.+]], label %[[OMP_INNER_FOR_END:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_INNER_FOR_BODY]]: // IR-NEXT: %[[TMP20:.+]] = load i32, ptr %[[DOTOMP_IV]], align 4 // IR-NEXT: %[[MUL:.+]] = mul i32 %[[TMP20]], 4 -// IR-NEXT: %[[ADD16:.+]] = add i32 0, %[[MUL]] -// IR-NEXT: store i32 %[[ADD16]], ptr %[[DOTFLOOR_0_IV_I12]], align 4 -// IR-NEXT: %[[TMP21:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I12]], align 4 +// IR-NEXT: %[[ADD15:.+]] = add i32 0, %[[MUL]] +// IR-NEXT: store i32 %[[ADD15]], ptr %[[DOTFLOOR_0_IV_I11]], align 4 +// IR-NEXT: %[[TMP21:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I11]], align 4 // IR-NEXT: store i32 %[[TMP21]], ptr %[[DOTTILE_0_IV_I]], align 4 // IR-NEXT: br label %[[FOR_COND:.+]] // IR-EMPTY: // IR-NEXT: [[FOR_COND]]: // IR-NEXT: %[[TMP22:.+]] = load i32, ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: %[[TMP23:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[ADD17:.+]] = add i32 %[[TMP23]], 1 -// IR-NEXT: %[[TMP24:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I12]], align 4 -// IR-NEXT: %[[ADD18:.+]] = add nsw i32 %[[TMP24]], 4 -// IR-NEXT: %[[CMP19:.+]] = icmp ult i32 %[[ADD17]], %[[ADD18]] -// IR-NEXT: br i1 %[[CMP19]], label %[[COND_TRUE20:.+]], label %[[COND_FALSE22:.+]] -// IR-EMPTY: -// IR-NEXT: [[COND_TRUE20]]: -// IR-NEXT: %[[TMP25:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[ADD21:.+]] = add i32 %[[TMP25]], 1 -// IR-NEXT: br label %[[COND_END24:.+]] -// IR-EMPTY: -// IR-NEXT: [[COND_FALSE22]]: -// IR-NEXT: %[[TMP26:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I12]], align 4 -// IR-NEXT: %[[ADD23:.+]] = add nsw i32 %[[TMP26]], 4 -// IR-NEXT: br label %[[COND_END24]] -// IR-EMPTY: -// IR-NEXT: [[COND_END24]]: -// IR-NEXT: %[[COND25:.+]] = phi i32 [ %[[ADD21]], %[[COND_TRUE20]] ], [ %[[ADD23]], %[[COND_FALSE22]] ] -// IR-NEXT: %[[CMP26:.+]] = icmp ult i32 %[[TMP22]], %[[COND25]] -// IR-NEXT: br i1 %[[CMP26]], label %[[FOR_BODY:.+]], label %[[FOR_END:.+]] +// IR-NEXT: %[[TMP23:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[ADD16:.+]] = add i32 %[[TMP23]], 1 +// IR-NEXT: %[[TMP24:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I11]], align 4 +// IR-NEXT: %[[ADD17:.+]] = add i32 %[[TMP24]], 4 +// IR-NEXT: %[[CMP18:.+]] = icmp ult i32 %[[ADD16]], %[[ADD17]] +// IR-NEXT: br i1 %[[CMP18]], label %[[COND_TRUE19:.+]], label %[[COND_FALSE21:.+]] +// IR-EMPTY: +// IR-NEXT: [[COND_TRUE19]]: +// IR-NEXT: %[[TMP25:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[ADD20:.+]] = add i32 %[[TMP25]], 1 +// IR-NEXT: br label %[[COND_END23:.+]] +// IR-EMPTY: +// IR-NEXT: [[COND_FALSE21]]: +// IR-NEXT: %[[TMP26:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I11]], align 4 +// IR-NEXT: %[[ADD22:.+]] = add i32 %[[TMP26]], 4 +// IR-NEXT: br label %[[COND_END23]] +// IR-EMPTY: +// IR-NEXT: [[COND_END23]]: +// IR-NEXT: %[[COND24:.+]] = phi i32 [ %[[ADD20]], %[[COND_TRUE19]] ], [ %[[ADD22]], %[[COND_FALSE21]] ] +// IR-NEXT: %[[CMP25:.+]] = icmp ult i32 %[[TMP22]], %[[COND24]] +// IR-NEXT: br i1 %[[CMP25]], label %[[FOR_BODY:.+]], label %[[FOR_END:.+]] // IR-EMPTY: // IR-NEXT: [[FOR_BODY]]: // IR-NEXT: %[[TMP27:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_]], align 4 // IR-NEXT: %[[TMP28:.+]] = load i32, ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: %[[TMP29:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 -// IR-NEXT: %[[MUL27:.+]] = mul i32 %[[TMP28]], %[[TMP29]] -// IR-NEXT: %[[ADD28:.+]] = add i32 %[[TMP27]], %[[MUL27]] -// IR-NEXT: store i32 %[[ADD28]], ptr %[[I]], align 4 +// IR-NEXT: %[[TMP29:.+]] = load i32, ptr %[[DOTNEW_STEP]], align 4 +// IR-NEXT: %[[MUL26:.+]] = mul i32 %[[TMP28]], %[[TMP29]] +// IR-NEXT: %[[ADD27:.+]] = add i32 %[[TMP27]], %[[MUL26]] +// IR-NEXT: store i32 %[[ADD27]], ptr %[[I]], align 4 // IR-NEXT: %[[TMP30:.+]] = load i32, ptr %[[START_ADDR]], align 4 // IR-NEXT: %[[TMP31:.+]] = load i32, ptr %[[END_ADDR]], align 4 // IR-NEXT: %[[TMP32:.+]] = load i32, ptr %[[STEP_ADDR]], align 4 @@ -156,9 +156,9 @@ extern "C" void body(...) {} // IR-EMPTY: // IR-NEXT: [[FOR_INC]]: // IR-NEXT: %[[TMP34:.+]] = load i32, ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: %[[INC:.+]] = add nsw i32 %[[TMP34]], 1 +// IR-NEXT: %[[INC:.+]] = add i32 %[[TMP34]], 1 // IR-NEXT: store i32 %[[INC]], ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: br label %[[FOR_COND]], !llvm.loop ![[LOOP2:[0-9]+]] +// IR-NEXT: br label %[[FOR_COND]], !llvm.loop ![[LOOP3:[0-9]+]] // IR-EMPTY: // IR-NEXT: [[FOR_END]]: // IR-NEXT: br label %[[OMP_BODY_CONTINUE:.+]] @@ -168,19 +168,19 @@ extern "C" void body(...) {} // IR-EMPTY: // IR-NEXT: [[OMP_INNER_FOR_INC]]: // IR-NEXT: %[[TMP35:.+]] = load i32, ptr %[[DOTOMP_IV]], align 4 -// IR-NEXT: %[[ADD29:.+]] = add i32 %[[TMP35]], 1 -// IR-NEXT: store i32 %[[ADD29]], ptr %[[DOTOMP_IV]], align 4 +// IR-NEXT: %[[ADD28:.+]] = add i32 %[[TMP35]], 1 +// IR-NEXT: store i32 %[[ADD28]], ptr %[[DOTOMP_IV]], align 4 // IR-NEXT: br label %[[OMP_INNER_FOR_COND]] // IR-EMPTY: // IR-NEXT: [[OMP_INNER_FOR_END]]: // IR-NEXT: br label %[[OMP_LOOP_EXIT:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_LOOP_EXIT]]: -// IR-NEXT: call void @__kmpc_for_static_fini(ptr @1, i32 %[[TMP0]]) +// IR-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 %[[TMP0]]) // IR-NEXT: br label %[[OMP_PRECOND_END]] // IR-EMPTY: // IR-NEXT: [[OMP_PRECOND_END]]: -// IR-NEXT: call void @__kmpc_barrier(ptr @3, i32 %[[TMP0]]) +// IR-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:.+]], i32 %[[TMP0]]) // IR-NEXT: ret void // IR-NEXT: } extern "C" void func(int start, int end, int step) { diff --git a/clang/test/OpenMP/tile_codegen_tile_for.cpp b/clang/test/OpenMP/tile_codegen_tile_for.cpp index d0fb89398c241..91536c406368b 100644 --- a/clang/test/OpenMP/tile_codegen_tile_for.cpp +++ b/clang/test/OpenMP/tile_codegen_tile_for.cpp @@ -16,7 +16,7 @@ extern "C" void body(...) {} -// IR-LABEL: @func( +// IR-LABEL: define {{.*}}@func( // IR-NEXT: [[ENTRY:.*]]: // IR-NEXT: %[[START_ADDR:.+]] = alloca i32, align 4 // IR-NEXT: %[[END_ADDR:.+]] = alloca i32, align 4 @@ -26,22 +26,22 @@ extern "C" void body(...) {} // IR-NEXT: %[[I:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTCAPTURE_EXPR_:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTCAPTURE_EXPR_1:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTNEW_STEP:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTCAPTURE_EXPR_2:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_3:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTFLOOR_0_IV_I:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_6:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_8:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_12:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTCAPTURE_EXPR_14:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTCAPTURE_EXPR_5:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTCAPTURE_EXPR_7:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTCAPTURE_EXPR_11:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTCAPTURE_EXPR_13:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTFLOOR_0_IV__FLOOR_0_IV_I:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_LB:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_UB:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_STRIDE:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTOMP_IS_LAST:.+]] = alloca i32, align 4 -// IR-NEXT: %[[DOTFLOOR_0_IV__FLOOR_0_IV_I18:.+]] = alloca i32, align 4 +// IR-NEXT: %[[DOTFLOOR_0_IV__FLOOR_0_IV_I17:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTTILE_0_IV__FLOOR_0_IV_I:.+]] = alloca i32, align 4 // IR-NEXT: %[[DOTTILE_0_IV_I:.+]] = alloca i32, align 4 -// IR-NEXT: %[[TMP0:.+]] = call i32 @__kmpc_global_thread_num(ptr @2) +// IR-NEXT: %[[TMP0:.+]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:.+]]) // IR-NEXT: store i32 %[[START:.+]], ptr %[[START_ADDR]], align 4 // IR-NEXT: store i32 %[[END:.+]], ptr %[[END_ADDR]], align 4 // IR-NEXT: store i32 %[[STEP:.+]], ptr %[[STEP_ADDR]], align 4 @@ -52,53 +52,53 @@ extern "C" void body(...) {} // IR-NEXT: %[[TMP3:.+]] = load i32, ptr %[[END_ADDR]], align 4 // IR-NEXT: store i32 %[[TMP3]], ptr %[[DOTCAPTURE_EXPR_1]], align 4 // IR-NEXT: %[[TMP4:.+]] = load i32, ptr %[[STEP_ADDR]], align 4 -// IR-NEXT: store i32 %[[TMP4]], ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: store i32 %[[TMP4]], ptr %[[DOTNEW_STEP]], align 4 // IR-NEXT: %[[TMP5:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_1]], align 4 // IR-NEXT: %[[TMP6:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_]], align 4 // IR-NEXT: %[[SUB:.+]] = sub i32 %[[TMP5]], %[[TMP6]] -// IR-NEXT: %[[SUB4:.+]] = sub i32 %[[SUB]], 1 -// IR-NEXT: %[[TMP7:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 -// IR-NEXT: %[[ADD:.+]] = add i32 %[[SUB4]], %[[TMP7]] -// IR-NEXT: %[[TMP8:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[SUB3:.+]] = sub i32 %[[SUB]], 1 +// IR-NEXT: %[[TMP7:.+]] = load i32, ptr %[[DOTNEW_STEP]], align 4 +// IR-NEXT: %[[ADD:.+]] = add i32 %[[SUB3]], %[[TMP7]] +// IR-NEXT: %[[TMP8:.+]] = load i32, ptr %[[DOTNEW_STEP]], align 4 // IR-NEXT: %[[DIV:.+]] = udiv i32 %[[ADD]], %[[TMP8]] -// IR-NEXT: %[[SUB5:.+]] = sub i32 %[[DIV]], 1 -// IR-NEXT: store i32 %[[SUB5]], ptr %[[DOTCAPTURE_EXPR_3]], align 4 +// IR-NEXT: %[[SUB4:.+]] = sub i32 %[[DIV]], 1 +// IR-NEXT: store i32 %[[SUB4]], ptr %[[DOTCAPTURE_EXPR_2]], align 4 // IR-NEXT: store i32 0, ptr %[[DOTFLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[TMP9:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[ADD7:.+]] = add i32 %[[TMP9]], 1 -// IR-NEXT: store i32 %[[ADD7]], ptr %[[DOTCAPTURE_EXPR_6]], align 4 -// IR-NEXT: %[[TMP10:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_6]], align 4 -// IR-NEXT: %[[SUB9:.+]] = sub i32 %[[TMP10]], -3 -// IR-NEXT: %[[DIV10:.+]] = udiv i32 %[[SUB9]], 4 -// IR-NEXT: %[[SUB11:.+]] = sub i32 %[[DIV10]], 1 -// IR-NEXT: store i32 %[[SUB11]], ptr %[[DOTCAPTURE_EXPR_8]], align 4 -// IR-NEXT: %[[TMP11:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_8]], align 4 -// IR-NEXT: %[[ADD13:.+]] = add i32 %[[TMP11]], 1 -// IR-NEXT: store i32 %[[ADD13]], ptr %[[DOTCAPTURE_EXPR_12]], align 4 -// IR-NEXT: %[[TMP12:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_12]], align 4 -// IR-NEXT: %[[SUB15:.+]] = sub i32 %[[TMP12]], -2 -// IR-NEXT: %[[DIV16:.+]] = udiv i32 %[[SUB15]], 3 -// IR-NEXT: %[[SUB17:.+]] = sub i32 %[[DIV16]], 1 -// IR-NEXT: store i32 %[[SUB17]], ptr %[[DOTCAPTURE_EXPR_14]], align 4 +// IR-NEXT: %[[TMP9:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[ADD6:.+]] = add i32 %[[TMP9]], 1 +// IR-NEXT: store i32 %[[ADD6]], ptr %[[DOTCAPTURE_EXPR_5]], align 4 +// IR-NEXT: %[[TMP10:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_5]], align 4 +// IR-NEXT: %[[SUB8:.+]] = sub i32 %[[TMP10]], -3 +// IR-NEXT: %[[DIV9:.+]] = udiv i32 %[[SUB8]], 4 +// IR-NEXT: %[[SUB10:.+]] = sub i32 %[[DIV9]], 1 +// IR-NEXT: store i32 %[[SUB10]], ptr %[[DOTCAPTURE_EXPR_7]], align 4 +// IR-NEXT: %[[TMP11:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_7]], align 4 +// IR-NEXT: %[[ADD12:.+]] = add i32 %[[TMP11]], 1 +// IR-NEXT: store i32 %[[ADD12]], ptr %[[DOTCAPTURE_EXPR_11]], align 4 +// IR-NEXT: %[[TMP12:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_11]], align 4 +// IR-NEXT: %[[SUB14:.+]] = sub i32 %[[TMP12]], -2 +// IR-NEXT: %[[DIV15:.+]] = udiv i32 %[[SUB14]], 3 +// IR-NEXT: %[[SUB16:.+]] = sub i32 %[[DIV15]], 1 +// IR-NEXT: store i32 %[[SUB16]], ptr %[[DOTCAPTURE_EXPR_13]], align 4 // IR-NEXT: store i32 0, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[TMP13:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_12]], align 4 +// IR-NEXT: %[[TMP13:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_11]], align 4 // IR-NEXT: %[[CMP:.+]] = icmp ult i32 0, %[[TMP13]] // IR-NEXT: br i1 %[[CMP]], label %[[OMP_PRECOND_THEN:.+]], label %[[OMP_PRECOND_END:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_PRECOND_THEN]]: // IR-NEXT: store i32 0, ptr %[[DOTOMP_LB]], align 4 -// IR-NEXT: %[[TMP14:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_14]], align 4 +// IR-NEXT: %[[TMP14:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_13]], align 4 // IR-NEXT: store i32 %[[TMP14]], ptr %[[DOTOMP_UB]], align 4 // IR-NEXT: store i32 1, ptr %[[DOTOMP_STRIDE]], align 4 // IR-NEXT: store i32 0, ptr %[[DOTOMP_IS_LAST]], align 4 -// IR-NEXT: call void @__kmpc_for_static_init_4u(ptr @1, i32 %[[TMP0]], i32 34, ptr %[[DOTOMP_IS_LAST]], ptr %[[DOTOMP_LB]], ptr %[[DOTOMP_UB]], ptr %[[DOTOMP_STRIDE]], i32 1, i32 1) +// IR-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1:.+]], i32 %[[TMP0]], i32 34, ptr %[[DOTOMP_IS_LAST]], ptr %[[DOTOMP_LB]], ptr %[[DOTOMP_UB]], ptr %[[DOTOMP_STRIDE]], i32 1, i32 1) // IR-NEXT: %[[TMP15:.+]] = load i32, ptr %[[DOTOMP_UB]], align 4 -// IR-NEXT: %[[TMP16:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_14]], align 4 -// IR-NEXT: %[[CMP19:.+]] = icmp ugt i32 %[[TMP15]], %[[TMP16]] -// IR-NEXT: br i1 %[[CMP19]], label %[[COND_TRUE:.+]], label %[[COND_FALSE:.+]] +// IR-NEXT: %[[TMP16:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_13]], align 4 +// IR-NEXT: %[[CMP18:.+]] = icmp ugt i32 %[[TMP15]], %[[TMP16]] +// IR-NEXT: br i1 %[[CMP18]], label %[[COND_TRUE:.+]], label %[[COND_FALSE:.+]] // IR-EMPTY: // IR-NEXT: [[COND_TRUE]]: -// IR-NEXT: %[[TMP17:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_14]], align 4 +// IR-NEXT: %[[TMP17:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_13]], align 4 // IR-NEXT: br label %[[COND_END:.+]] // IR-EMPTY: // IR-NEXT: [[COND_FALSE]]: @@ -115,83 +115,83 @@ extern "C" void body(...) {} // IR-NEXT: [[OMP_INNER_FOR_COND]]: // IR-NEXT: %[[TMP20:.+]] = load i32, ptr %[[DOTOMP_IV]], align 4 // IR-NEXT: %[[TMP21:.+]] = load i32, ptr %[[DOTOMP_UB]], align 4 -// IR-NEXT: %[[ADD20:.+]] = add i32 %[[TMP21]], 1 -// IR-NEXT: %[[CMP21:.+]] = icmp ult i32 %[[TMP20]], %[[ADD20]] -// IR-NEXT: br i1 %[[CMP21]], label %[[OMP_INNER_FOR_BODY:.+]], label %[[OMP_INNER_FOR_END:.+]] +// IR-NEXT: %[[ADD19:.+]] = add i32 %[[TMP21]], 1 +// IR-NEXT: %[[CMP20:.+]] = icmp ult i32 %[[TMP20]], %[[ADD19]] +// IR-NEXT: br i1 %[[CMP20]], label %[[OMP_INNER_FOR_BODY:.+]], label %[[OMP_INNER_FOR_END:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_INNER_FOR_BODY]]: // IR-NEXT: %[[TMP22:.+]] = load i32, ptr %[[DOTOMP_IV]], align 4 // IR-NEXT: %[[MUL:.+]] = mul i32 %[[TMP22]], 3 -// IR-NEXT: %[[ADD22:.+]] = add i32 0, %[[MUL]] -// IR-NEXT: store i32 %[[ADD22]], ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I18]], align 4 -// IR-NEXT: %[[TMP23:.+]] = load i32, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I18]], align 4 +// IR-NEXT: %[[ADD21:.+]] = add i32 0, %[[MUL]] +// IR-NEXT: store i32 %[[ADD21]], ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I17]], align 4 +// IR-NEXT: %[[TMP23:.+]] = load i32, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I17]], align 4 // IR-NEXT: store i32 %[[TMP23]], ptr %[[DOTTILE_0_IV__FLOOR_0_IV_I]], align 4 // IR-NEXT: br label %[[FOR_COND:.+]] // IR-EMPTY: // IR-NEXT: [[FOR_COND]]: // IR-NEXT: %[[TMP24:.+]] = load i32, ptr %[[DOTTILE_0_IV__FLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[TMP25:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_8]], align 4 -// IR-NEXT: %[[ADD23:.+]] = add i32 %[[TMP25]], 1 -// IR-NEXT: %[[TMP26:.+]] = load i32, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I18]], align 4 -// IR-NEXT: %[[ADD24:.+]] = add i32 %[[TMP26]], 3 -// IR-NEXT: %[[CMP25:.+]] = icmp ult i32 %[[ADD23]], %[[ADD24]] -// IR-NEXT: br i1 %[[CMP25]], label %[[COND_TRUE26:.+]], label %[[COND_FALSE28:.+]] -// IR-EMPTY: -// IR-NEXT: [[COND_TRUE26]]: -// IR-NEXT: %[[TMP27:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_8]], align 4 -// IR-NEXT: %[[ADD27:.+]] = add i32 %[[TMP27]], 1 -// IR-NEXT: br label %[[COND_END30:.+]] -// IR-EMPTY: -// IR-NEXT: [[COND_FALSE28]]: -// IR-NEXT: %[[TMP28:.+]] = load i32, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I18]], align 4 -// IR-NEXT: %[[ADD29:.+]] = add i32 %[[TMP28]], 3 -// IR-NEXT: br label %[[COND_END30]] -// IR-EMPTY: -// IR-NEXT: [[COND_END30]]: -// IR-NEXT: %[[COND31:.+]] = phi i32 [ %[[ADD27]], %[[COND_TRUE26]] ], [ %[[ADD29]], %[[COND_FALSE28]] ] -// IR-NEXT: %[[CMP32:.+]] = icmp ult i32 %[[TMP24]], %[[COND31]] -// IR-NEXT: br i1 %[[CMP32]], label %[[FOR_BODY:.+]], label %[[FOR_END51:.+]] +// IR-NEXT: %[[TMP25:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_7]], align 4 +// IR-NEXT: %[[ADD22:.+]] = add i32 %[[TMP25]], 1 +// IR-NEXT: %[[TMP26:.+]] = load i32, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I17]], align 4 +// IR-NEXT: %[[ADD23:.+]] = add i32 %[[TMP26]], 3 +// IR-NEXT: %[[CMP24:.+]] = icmp ult i32 %[[ADD22]], %[[ADD23]] +// IR-NEXT: br i1 %[[CMP24]], label %[[COND_TRUE25:.+]], label %[[COND_FALSE27:.+]] +// IR-EMPTY: +// IR-NEXT: [[COND_TRUE25]]: +// IR-NEXT: %[[TMP27:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_7]], align 4 +// IR-NEXT: %[[ADD26:.+]] = add i32 %[[TMP27]], 1 +// IR-NEXT: br label %[[COND_END29:.+]] +// IR-EMPTY: +// IR-NEXT: [[COND_FALSE27]]: +// IR-NEXT: %[[TMP28:.+]] = load i32, ptr %[[DOTFLOOR_0_IV__FLOOR_0_IV_I17]], align 4 +// IR-NEXT: %[[ADD28:.+]] = add i32 %[[TMP28]], 3 +// IR-NEXT: br label %[[COND_END29]] +// IR-EMPTY: +// IR-NEXT: [[COND_END29]]: +// IR-NEXT: %[[COND30:.+]] = phi i32 [ %[[ADD26]], %[[COND_TRUE25]] ], [ %[[ADD28]], %[[COND_FALSE27]] ] +// IR-NEXT: %[[CMP31:.+]] = icmp ult i32 %[[TMP24]], %[[COND30]] +// IR-NEXT: br i1 %[[CMP31]], label %[[FOR_BODY:.+]], label %[[FOR_END50:.+]] // IR-EMPTY: // IR-NEXT: [[FOR_BODY]]: // IR-NEXT: %[[TMP29:.+]] = load i32, ptr %[[DOTTILE_0_IV__FLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[MUL33:.+]] = mul i32 %[[TMP29]], 4 -// IR-NEXT: %[[ADD34:.+]] = add i32 0, %[[MUL33]] -// IR-NEXT: store i32 %[[ADD34]], ptr %[[DOTFLOOR_0_IV_I]], align 4 +// IR-NEXT: %[[MUL32:.+]] = mul i32 %[[TMP29]], 4 +// IR-NEXT: %[[ADD33:.+]] = add i32 0, %[[MUL32]] +// IR-NEXT: store i32 %[[ADD33]], ptr %[[DOTFLOOR_0_IV_I]], align 4 // IR-NEXT: %[[TMP30:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I]], align 4 // IR-NEXT: store i32 %[[TMP30]], ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: br label %[[FOR_COND35:.+]] +// IR-NEXT: br label %[[FOR_COND34:.+]] // IR-EMPTY: -// IR-NEXT: [[FOR_COND35]]: +// IR-NEXT: [[FOR_COND34]]: // IR-NEXT: %[[TMP31:.+]] = load i32, ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: %[[TMP32:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[ADD36:.+]] = add i32 %[[TMP32]], 1 +// IR-NEXT: %[[TMP32:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[ADD35:.+]] = add i32 %[[TMP32]], 1 // IR-NEXT: %[[TMP33:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[ADD37:.+]] = add nsw i32 %[[TMP33]], 4 -// IR-NEXT: %[[CMP38:.+]] = icmp ult i32 %[[ADD36]], %[[ADD37]] -// IR-NEXT: br i1 %[[CMP38]], label %[[COND_TRUE39:.+]], label %[[COND_FALSE41:.+]] +// IR-NEXT: %[[ADD36:.+]] = add i32 %[[TMP33]], 4 +// IR-NEXT: %[[CMP37:.+]] = icmp ult i32 %[[ADD35]], %[[ADD36]] +// IR-NEXT: br i1 %[[CMP37]], label %[[COND_TRUE38:.+]], label %[[COND_FALSE40:.+]] // IR-EMPTY: -// IR-NEXT: [[COND_TRUE39]]: -// IR-NEXT: %[[TMP34:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_3]], align 4 -// IR-NEXT: %[[ADD40:.+]] = add i32 %[[TMP34]], 1 -// IR-NEXT: br label %[[COND_END43:.+]] +// IR-NEXT: [[COND_TRUE38]]: +// IR-NEXT: %[[TMP34:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 +// IR-NEXT: %[[ADD39:.+]] = add i32 %[[TMP34]], 1 +// IR-NEXT: br label %[[COND_END42:.+]] // IR-EMPTY: -// IR-NEXT: [[COND_FALSE41]]: +// IR-NEXT: [[COND_FALSE40]]: // IR-NEXT: %[[TMP35:.+]] = load i32, ptr %[[DOTFLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[ADD42:.+]] = add nsw i32 %[[TMP35]], 4 -// IR-NEXT: br label %[[COND_END43]] +// IR-NEXT: %[[ADD41:.+]] = add i32 %[[TMP35]], 4 +// IR-NEXT: br label %[[COND_END42]] // IR-EMPTY: -// IR-NEXT: [[COND_END43]]: -// IR-NEXT: %[[COND44:.+]] = phi i32 [ %[[ADD40]], %[[COND_TRUE39]] ], [ %[[ADD42]], %[[COND_FALSE41]] ] -// IR-NEXT: %[[CMP45:.+]] = icmp ult i32 %[[TMP31]], %[[COND44]] -// IR-NEXT: br i1 %[[CMP45]], label %[[FOR_BODY46:.+]], label %[[FOR_END:.+]] +// IR-NEXT: [[COND_END42]]: +// IR-NEXT: %[[COND43:.+]] = phi i32 [ %[[ADD39]], %[[COND_TRUE38]] ], [ %[[ADD41]], %[[COND_FALSE40]] ] +// IR-NEXT: %[[CMP44:.+]] = icmp ult i32 %[[TMP31]], %[[COND43]] +// IR-NEXT: br i1 %[[CMP44]], label %[[FOR_BODY45:.+]], label %[[FOR_END:.+]] // IR-EMPTY: -// IR-NEXT: [[FOR_BODY46]]: +// IR-NEXT: [[FOR_BODY45]]: // IR-NEXT: %[[TMP36:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_]], align 4 // IR-NEXT: %[[TMP37:.+]] = load i32, ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: %[[TMP38:.+]] = load i32, ptr %[[DOTCAPTURE_EXPR_2]], align 4 -// IR-NEXT: %[[MUL47:.+]] = mul i32 %[[TMP37]], %[[TMP38]] -// IR-NEXT: %[[ADD48:.+]] = add i32 %[[TMP36]], %[[MUL47]] -// IR-NEXT: store i32 %[[ADD48]], ptr %[[I]], align 4 +// IR-NEXT: %[[TMP38:.+]] = load i32, ptr %[[DOTNEW_STEP]], align 4 +// IR-NEXT: %[[MUL46:.+]] = mul i32 %[[TMP37]], %[[TMP38]] +// IR-NEXT: %[[ADD47:.+]] = add i32 %[[TMP36]], %[[MUL46]] +// IR-NEXT: store i32 %[[ADD47]], ptr %[[I]], align 4 // IR-NEXT: %[[TMP39:.+]] = load i32, ptr %[[START_ADDR]], align 4 // IR-NEXT: %[[TMP40:.+]] = load i32, ptr %[[END_ADDR]], align 4 // IR-NEXT: %[[TMP41:.+]] = load i32, ptr %[[STEP_ADDR]], align 4 @@ -201,20 +201,20 @@ extern "C" void body(...) {} // IR-EMPTY: // IR-NEXT: [[FOR_INC]]: // IR-NEXT: %[[TMP43:.+]] = load i32, ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: %[[INC:.+]] = add nsw i32 %[[TMP43]], 1 +// IR-NEXT: %[[INC:.+]] = add i32 %[[TMP43]], 1 // IR-NEXT: store i32 %[[INC]], ptr %[[DOTTILE_0_IV_I]], align 4 -// IR-NEXT: br label %[[FOR_COND35]], !llvm.loop ![[LOOP2:[0-9]+]] +// IR-NEXT: br label %[[FOR_COND34]], !llvm.loop ![[LOOP3:[0-9]+]] // IR-EMPTY: // IR-NEXT: [[FOR_END]]: -// IR-NEXT: br label %[[FOR_INC49:.+]] +// IR-NEXT: br label %[[FOR_INC48:.+]] // IR-EMPTY: -// IR-NEXT: [[FOR_INC49]]: +// IR-NEXT: [[FOR_INC48]]: // IR-NEXT: %[[TMP44:.+]] = load i32, ptr %[[DOTTILE_0_IV__FLOOR_0_IV_I]], align 4 -// IR-NEXT: %[[INC50:.+]] = add i32 %[[TMP44]], 1 -// IR-NEXT: store i32 %[[INC50]], ptr %[[DOTTILE_0_IV__FLOOR_0_IV_I]], align 4 -// IR-NEXT: br label %[[FOR_COND]], !llvm.loop ![[LOOP4:[0-9]+]] +// IR-NEXT: %[[INC49:.+]] = add i32 %[[TMP44]], 1 +// IR-NEXT: store i32 %[[INC49]], ptr %[[DOTTILE_0_IV__FLOOR_0_IV_I]], align 4 +// IR-NEXT: br label %[[FOR_COND]], !llvm.loop ![[LOOP5:[0-9]+]] // IR-EMPTY: -// IR-NEXT: [[FOR_END51]]: +// IR-NEXT: [[FOR_END50]]: // IR-NEXT: br label %[[OMP_BODY_CONTINUE:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_BODY_CONTINUE]]: @@ -222,21 +222,23 @@ extern "C" void body(...) {} // IR-EMPTY: // IR-NEXT: [[OMP_INNER_FOR_INC]]: // IR-NEXT: %[[TMP45:.+]] = load i32, ptr %[[DOTOMP_IV]], align 4 -// IR-NEXT: %[[ADD52:.+]] = add i32 %[[TMP45]], 1 -// IR-NEXT: store i32 %[[ADD52]], ptr %[[DOTOMP_IV]], align 4 +// IR-NEXT: %[[ADD51:.+]] = add i32 %[[TMP45]], 1 +// IR-NEXT: store i32 %[[ADD51]], ptr %[[DOTOMP_IV]], align 4 // IR-NEXT: br label %[[OMP_INNER_FOR_COND]] // IR-EMPTY: // IR-NEXT: [[OMP_INNER_FOR_END]]: // IR-NEXT: br label %[[OMP_LOOP_EXIT:.+]] // IR-EMPTY: // IR-NEXT: [[OMP_LOOP_EXIT]]: -// IR-NEXT: call void @__kmpc_for_static_fini(ptr @1, i32 %[[TMP0]]) +// IR-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 %[[TMP0]]) // IR-NEXT: br label %[[OMP_PRECOND_END]] // IR-EMPTY: // IR-NEXT: [[OMP_PRECOND_END]]: -// IR-NEXT: call void @__kmpc_barrier(ptr @3, i32 %[[TMP0]]) +// IR-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:.+]], i32 %[[TMP0]]) // IR-NEXT: ret void // IR-NEXT: } + + extern "C" void func(int start, int end, int step) { #pragma omp for #pragma omp tile sizes(3) @@ -246,8 +248,10 @@ extern "C" void func(int start, int end, int step) { } #endif /* HEADER */ + // IR: ![[META0:[0-9]+]] = !{i32 1, !"wchar_size", i32 4} -// IR: ![[META1:[0-9]+]] = !{!"{{[^"]*}}"} -// IR: ![[LOOP2]] = distinct !{![[LOOP2]], ![[LOOPPROP3:[0-9]+]]} -// IR: ![[LOOPPROP3]] = !{!"llvm.loop.mustprogress"} -// IR: ![[LOOP4]] = distinct !{![[LOOP4]], ![[LOOPPROP3]]} +// IR: ![[META1:[0-9]+]] = !{i32 7, !"openmp", i32 51} +// IR: ![[META2:[0-9]+]] = +// IR: ![[LOOP3]] = distinct !{![[LOOP3]], ![[LOOPPROP4:[0-9]+]]} +// IR: ![[LOOPPROP4]] = !{!"llvm.loop.mustprogress"} +// IR: ![[LOOP5]] = distinct !{![[LOOP5]], ![[LOOPPROP4]]} diff --git a/clang/test/PCH/cxx1z-aligned-alloc.cpp b/clang/test/PCH/cxx1z-aligned-alloc.cpp index c1becbde3bf2c..cccd628597845 100644 --- a/clang/test/PCH/cxx1z-aligned-alloc.cpp +++ b/clang/test/PCH/cxx1z-aligned-alloc.cpp @@ -1,12 +1,12 @@ // No PCH: -// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -include %s -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -include %s -verify %s // // With PCH: -// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -emit-pch %s -o %t -// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s -// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -emit-pch -fpch-instantiate-templates %s -o %t -// RUN: %clang_cc1 -pedantic -fsized-deallocation -std=c++1z -include-pch %t -verify %s +// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch -fpch-instantiate-templates %s -o %t +// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s // expected-no-diagnostics diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp index 6bf802a29ace3..9102bca8f6bb2 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -426,7 +426,7 @@ bool f(int); template struct A { constexpr A(T t) { - __assume(f(t)); // expected-warning{{the argument to '__assume' has side effects that will be discarded}} + __assume(f(t)); // expected-warning{{assumption is ignored because it contains (potential) side-effects}} } constexpr bool g() { return false; } }; diff --git a/clang/test/Parser/altivec.c b/clang/test/Parser/altivec.c index 445369f0dc066..9291b9b69160f 100644 --- a/clang/test/Parser/altivec.c +++ b/clang/test/Parser/altivec.c @@ -56,40 +56,40 @@ void f_a2(int b, vector int a); vector int v = (vector int)(-1); // These should have errors on AIX and warnings otherwise. -__vector long vv_l; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector long vv_l; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector signed long vv_sl; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector signed long vv_sl; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector unsigned long vv_ul; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector unsigned long vv_ul; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector long int vv_li; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector long int vv_li; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector signed long int vv_sli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector signed long int vv_sli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector unsigned long int vv_uli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector unsigned long int vv_uli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector long v_l; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector long v_l; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector signed long v_sl; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector signed long v_sl; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector unsigned long v_ul; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector unsigned long v_ul; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector long int v_li; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector long int v_li; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector signed long int v_sli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector signed long int v_sli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector unsigned long int v_uli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector unsigned long int v_uli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} diff --git a/clang/test/Parser/cxx-altivec.cpp b/clang/test/Parser/cxx-altivec.cpp index 5cb760dababbb..15a6bf6d1be80 100644 --- a/clang/test/Parser/cxx-altivec.cpp +++ b/clang/test/Parser/cxx-altivec.cpp @@ -59,40 +59,40 @@ void f_a2(int b, vector int a); vector int v = (vector int)(-1); // These should have errors on AIX and warnings otherwise. -__vector long vv_l; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector long vv_l; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector signed long vv_sl; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector signed long vv_sl; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector unsigned long vv_ul; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector unsigned long vv_ul; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector long int vv_li; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector long int vv_li; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector signed long int vv_sli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector signed long int vv_sli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -__vector unsigned long int vv_uli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +__vector unsigned long int vv_uli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector long v_l; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector long v_l; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector signed long v_sl; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector signed long v_sl; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector unsigned long v_ul; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector unsigned long v_ul; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector long int v_li; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector long int v_li; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector signed long int v_sli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector signed long int v_sli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} -vector unsigned long int v_uli; // nonaix-warning {{Use of 'long' with '__vector' is deprecated}} +vector unsigned long int v_uli; // nonaix-warning {{use of 'long' with '__vector' is deprecated}} // aix-error@-1 {{cannot use 'long' with '__vector'}} // novsx-error@-2 {{cannot use 'long' with '__vector'}} diff --git a/clang/test/Parser/lax-conv.cpp b/clang/test/Parser/lax-conv.cpp index f784e3fa74e7e..0cb2503a96910 100644 --- a/clang/test/Parser/lax-conv.cpp +++ b/clang/test/Parser/lax-conv.cpp @@ -21,10 +21,10 @@ template VEC __attribute__((noinline)) test(vector unsigned char return (VEC)(a * b); } vector unsigned int test1(vector unsigned char RetImplicitConv) { - return RetImplicitConv; // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + return RetImplicitConv; // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } vector unsigned int test2(vector unsigned char RetImplicitConvAddConst) { - return RetImplicitConvAddConst + 5; // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + return RetImplicitConvAddConst + 5; // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } vector unsigned int test3(vector unsigned char RetExplicitConv) { return (vector unsigned int)RetExplicitConv; @@ -34,7 +34,7 @@ vector unsigned int test4(vector unsigned char RetExplicitConvAddConst) { } vector unsigned int test5(vector unsigned char RetImplicitConvAddSame1, vector unsigned char RetImplicitConvAddSame2) { - return RetImplicitConvAddSame1 + RetImplicitConvAddSame2; // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + return RetImplicitConvAddSame1 + RetImplicitConvAddSame2; // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } vector unsigned int test6(vector unsigned char RetExplicitConvAddSame1, vector unsigned char RetExplicitConvAddSame2) { @@ -54,10 +54,10 @@ vector unsigned long long test9(vector unsigned char a, vector unsigned char b) return test(a, b); } void test1a(vector unsigned char ArgImplicitConv) { - return dummy(ArgImplicitConv); // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + return dummy(ArgImplicitConv); // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } void test2a(vector unsigned char ArgImplicitConvAddConst) { - return dummy(ArgImplicitConvAddConst + 5); // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + return dummy(ArgImplicitConvAddConst + 5); // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } void test3a(vector unsigned char ArgExplicitConv) { return dummy((vector unsigned int)ArgExplicitConv); @@ -67,7 +67,7 @@ void test4a(vector unsigned char ArgExplicitConvAddConst) { } void test5a(vector unsigned char ArgImplicitConvAddSame1, vector unsigned char ArgImplicitConvAddSame2) { - return dummy(ArgImplicitConvAddSame1 + ArgImplicitConvAddSame2); // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + return dummy(ArgImplicitConvAddSame1 + ArgImplicitConvAddSame2); // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } void test6a(vector unsigned char ArgExplicitConvAddSame1, vector unsigned char ArgExplicitConvAddSame2) { @@ -80,33 +80,33 @@ void test7a(vector unsigned char ArgExplicitConvAddSame1Full, ArgExplicitConvAddSame2Full)); } void test_bool_compat(void) { - vbs = vss; // expected-warning {{Implicit conversion between vector types (''__vector short' (vector of 8 'short' values)' and ''__vector __bool unsigned short' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vbs = vus; // expected-warning {{Implicit conversion between vector types (''__vector unsigned short' (vector of 8 'unsigned short' values)' and ''__vector __bool unsigned short' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vbs = vss; // expected-warning {{implicit conversion between vector types (''__vector short' (vector of 8 'short' values)' and ''__vector __bool unsigned short' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vbs = vus; // expected-warning {{implicit conversion between vector types (''__vector unsigned short' (vector of 8 'unsigned short' values)' and ''__vector __bool unsigned short' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} - vbi = vsi; // expected-warning {{Implicit conversion between vector types (''__vector int' (vector of 4 'int' values)' and ''__vector __bool unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vbi = vui; // expected-warning {{Implicit conversion between vector types (''__vector unsigned int' (vector of 4 'unsigned int' values)' and ''__vector __bool unsigned int' (vector of 4 'unsigned int' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vbi = vsi; // expected-warning {{implicit conversion between vector types (''__vector int' (vector of 4 'int' values)' and ''__vector __bool unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vbi = vui; // expected-warning {{implicit conversion between vector types (''__vector unsigned int' (vector of 4 'unsigned int' values)' and ''__vector __bool unsigned int' (vector of 4 'unsigned int' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} - vbl = vsl; // expected-warning {{Implicit conversion between vector types (''__vector long long' (vector of 2 'long long' values)' and ''__vector __bool unsigned long long' (vector of 2 'unsigned long long' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vbl = vul; // expected-warning {{Implicit conversion between vector types (''__vector unsigned long long' (vector of 2 'unsigned long long' values)' and ''__vector __bool unsigned long long' (vector of 2 'unsigned long long' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vbl = vsl; // expected-warning {{implicit conversion between vector types (''__vector long long' (vector of 2 'long long' values)' and ''__vector __bool unsigned long long' (vector of 2 'unsigned long long' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vbl = vul; // expected-warning {{implicit conversion between vector types (''__vector unsigned long long' (vector of 2 'unsigned long long' values)' and ''__vector __bool unsigned long long' (vector of 2 'unsigned long long' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} - vbc = vsc; // expected-warning {{Implicit conversion between vector types (''__vector signed char' (vector of 16 'signed char' values)' and ''__vector __bool unsigned char' (vector of 16 'unsigned char' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vbc = vuc; // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector __bool unsigned char' (vector of 16 'unsigned char' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vbc = vsc; // expected-warning {{implicit conversion between vector types (''__vector signed char' (vector of 16 'signed char' values)' and ''__vector __bool unsigned char' (vector of 16 'unsigned char' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vbc = vuc; // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector __bool unsigned char' (vector of 16 'unsigned char' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } void test_pixel_compat(void) { - vp = vbs; // expected-warning {{Implicit conversion between vector types (''__vector __bool unsigned short' (vector of 8 'unsigned short' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vss; // expected-warning {{Implicit conversion between vector types (''__vector short' (vector of 8 'short' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vus; // expected-warning {{Implicit conversion between vector types (''__vector unsigned short' (vector of 8 'unsigned short' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vp = vbs; // expected-warning {{implicit conversion between vector types (''__vector __bool unsigned short' (vector of 8 'unsigned short' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vss; // expected-warning {{implicit conversion between vector types (''__vector short' (vector of 8 'short' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vus; // expected-warning {{implicit conversion between vector types (''__vector unsigned short' (vector of 8 'unsigned short' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} - vp = vbi; // expected-warning {{Implicit conversion between vector types (''__vector __bool unsigned int' (vector of 4 'unsigned int' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vsi; // expected-warning {{Implicit conversion between vector types (''__vector int' (vector of 4 'int' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vui; // expected-warning {{Implicit conversion between vector types (''__vector unsigned int' (vector of 4 'unsigned int' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vp = vbi; // expected-warning {{implicit conversion between vector types (''__vector __bool unsigned int' (vector of 4 'unsigned int' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vsi; // expected-warning {{implicit conversion between vector types (''__vector int' (vector of 4 'int' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vui; // expected-warning {{implicit conversion between vector types (''__vector unsigned int' (vector of 4 'unsigned int' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} - vp = vbl; // expected-warning {{Implicit conversion between vector types (''__vector __bool unsigned long long' (vector of 2 'unsigned long long' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vsl; // expected-warning {{Implicit conversion between vector types (''__vector long long' (vector of 2 'long long' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vul; // expected-warning {{Implicit conversion between vector types (''__vector unsigned long long' (vector of 2 'unsigned long long' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vp = vbl; // expected-warning {{implicit conversion between vector types (''__vector __bool unsigned long long' (vector of 2 'unsigned long long' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vsl; // expected-warning {{implicit conversion between vector types (''__vector long long' (vector of 2 'long long' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vul; // expected-warning {{implicit conversion between vector types (''__vector unsigned long long' (vector of 2 'unsigned long long' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} - vp = vbc; // expected-warning {{Implicit conversion between vector types (''__vector __bool unsigned char' (vector of 16 'unsigned char' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vsc; // expected-warning {{Implicit conversion between vector types (''__vector signed char' (vector of 16 'signed char' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} - vp = vuc; // expected-warning {{Implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated. In the future, the behavior implied by '-fno-lax-vector-conversions' will be the default.}} + vp = vbc; // expected-warning {{implicit conversion between vector types (''__vector __bool unsigned char' (vector of 16 'unsigned char' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vsc; // expected-warning {{implicit conversion between vector types (''__vector signed char' (vector of 16 'signed char' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} + vp = vuc; // expected-warning {{implicit conversion between vector types (''__vector unsigned char' (vector of 16 'unsigned char' values)' and ''__vector __pixel ' (vector of 8 'unsigned short' values)') is deprecated; in the future, the behavior implied by '-fno-lax-vector-conversions' will be the default}} } diff --git a/clang/test/Parser/objcbridge-related-attribute.m b/clang/test/Parser/objcbridge-related-attribute.m index 246afeef5198e..e76d5e3881414 100644 --- a/clang/test/Parser/objcbridge-related-attribute.m +++ b/clang/test/Parser/objcbridge-related-attribute.m @@ -5,10 +5,10 @@ typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor *CGColorRef2Ok; typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,))) CGColor *CGColorRef3Ok; -typedef struct __attribute__((objc_bridge_related(,colorWithCGColor:,CGColor))) CGColor *CGColorRef1NotOk; // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}} +typedef struct __attribute__((objc_bridge_related(,colorWithCGColor:,CGColor))) CGColor *CGColorRef1NotOk; // expected-error {{expected a related Objective-C class name, e.g., 'NSColor'}} typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor,CGColor))) CGColor *CGColorRef2NotOk; // expected-error {{expected a class method selector with single argument, e.g., 'colorWithCGColor:'}} typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor::,CGColor))) CGColor *CGColorRef3NotOk; // expected-error {{expected a class method selector with single argument, e.g., 'colorWithCGColor:'}} -typedef struct __attribute__((objc_bridge_related(12,colorWithCGColor:,CGColor))) CGColor *CGColorRef4NotOk; // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}} +typedef struct __attribute__((objc_bridge_related(12,colorWithCGColor:,CGColor))) CGColor *CGColorRef4NotOk; // expected-error {{expected a related Objective-C class name, e.g., 'NSColor'}} typedef struct __attribute__((objc_bridge_related(NSColor,+:,CGColor))) CGColor *CGColorRef5NotOk; // expected-error {{expected ','}} typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,+))) CGColor *CGColorRef6NotOk; // expected-error {{expected ')'}} diff --git a/clang/test/Parser/pragma-attribute.cpp b/clang/test/Parser/pragma-attribute.cpp index bc8e7b9e78c6f..6377fc754352e 100644 --- a/clang/test/Parser/pragma-attribute.cpp +++ b/clang/test/Parser/pragma-attribute.cpp @@ -127,7 +127,7 @@ void function(); // expected-error@-1 {{attribute 'objc_bridge_related' can't be applied to 'function'}} #pragma clang attribute pop -#pragma clang attribute push (__attribute__((objc_bridge_related(1))), apply_to=function) // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}} +#pragma clang attribute push (__attribute__((objc_bridge_related(1))), apply_to=function) // expected-error {{expected a related Objective-C class name, e.g., 'NSColor'}} #pragma clang attribute push (__attribute__((used)), apply_to=function) // expected-error {{attribute 'used' is not supported by '#pragma clang attribute'}} diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index 694f28b86ec9f..49e749feb2ec7 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -831,52 +831,38 @@ void ReductionClauseParsing() { // expected-error@+1{{expected '('}} #pragma acc serial reduction for(;;){} - // expected-error@+3{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} + // expected-error@+2{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} + // expected-error@+1{{expected expression}} #pragma acc serial reduction() for(;;){} - // expected-error@+2{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} + // expected-error@+1{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} #pragma acc serial reduction(Begin) for(;;){} - // expected-error@+2{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} + // expected-error@+1{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} #pragma acc serial reduction(Begin, End) for(;;){} - // expected-error@+2{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} + // expected-error@+1{{missing reduction operator, expected '+', '*', 'max', 'min', '&', '|', '^', '&&', or '||', follwed by a ':'}} #pragma acc serial reduction(Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(+:Begin) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(+:Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(*: Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(max : Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(min: Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(&: Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(|: Begin, End) for(;;){} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} #pragma acc serial reduction(^: Begin, End) for(;;){} - // expected-warning@+2{{OpenACC clause 'seq' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented, clause ignored}} + // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} #pragma acc serial seq, reduction(&&: Begin, End) for(;;){} - // expected-warning@+2{{OpenACC clause 'reduction' not yet implemented, clause ignored}} // expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}} #pragma acc serial reduction(||: Begin, End), seq for(;;){} diff --git a/clang/test/Preprocessor/predefined-arch-macros.c b/clang/test/Preprocessor/predefined-arch-macros.c index ca51f2fc22c51..f0a2ef851287f 100644 --- a/clang/test/Preprocessor/predefined-arch-macros.c +++ b/clang/test/Preprocessor/predefined-arch-macros.c @@ -793,9 +793,7 @@ // CHECK_KNL_M32: #define __AES__ 1 // CHECK_KNL_M32: #define __AVX2__ 1 // CHECK_KNL_M32: #define __AVX512CD__ 1 -// CHECK_KNL_M32: #define __AVX512ER__ 1 // CHECK_KNL_M32: #define __AVX512F__ 1 -// CHECK_KNL_M32: #define __AVX512PF__ 1 // CHECK_KNL_M32: #define __AVX__ 1 // CHECK_KNL_M32: #define __BMI2__ 1 // CHECK_KNL_M32: #define __BMI__ 1 @@ -808,7 +806,6 @@ // CHECK_KNL_M32: #define __MOVBE__ 1 // CHECK_KNL_M32: #define __PCLMUL__ 1 // CHECK_KNL_M32: #define __POPCNT__ 1 -// CHECK_KNL_M32: #define __PREFETCHWT1__ 1 // CHECK_KNL_M32: #define __PRFCHW__ 1 // CHECK_KNL_M32: #define __RDRND__ 1 // CHECK_KNL_M32: #define __SSE2__ 1 @@ -832,9 +829,7 @@ // CHECK_KNL_M64: #define __AES__ 1 // CHECK_KNL_M64: #define __AVX2__ 1 // CHECK_KNL_M64: #define __AVX512CD__ 1 -// CHECK_KNL_M64: #define __AVX512ER__ 1 // CHECK_KNL_M64: #define __AVX512F__ 1 -// CHECK_KNL_M64: #define __AVX512PF__ 1 // CHECK_KNL_M64: #define __AVX__ 1 // CHECK_KNL_M64: #define __BMI2__ 1 // CHECK_KNL_M64: #define __BMI__ 1 @@ -847,7 +842,6 @@ // CHECK_KNL_M64: #define __MOVBE__ 1 // CHECK_KNL_M64: #define __PCLMUL__ 1 // CHECK_KNL_M64: #define __POPCNT__ 1 -// CHECK_KNL_M64: #define __PREFETCHWT1__ 1 // CHECK_KNL_M64: #define __PRFCHW__ 1 // CHECK_KNL_M64: #define __RDRND__ 1 // CHECK_KNL_M64: #define __SSE2_MATH__ 1 @@ -874,9 +868,7 @@ // CHECK_KNM_M32: #define __AES__ 1 // CHECK_KNM_M32: #define __AVX2__ 1 // CHECK_KNM_M32: #define __AVX512CD__ 1 -// CHECK_KNM_M32: #define __AVX512ER__ 1 // CHECK_KNM_M32: #define __AVX512F__ 1 -// CHECK_KNM_M32: #define __AVX512PF__ 1 // CHECK_KNM_M32: #define __AVX512VPOPCNTDQ__ 1 // CHECK_KNM_M32: #define __AVX__ 1 // CHECK_KNM_M32: #define __BMI2__ 1 @@ -890,7 +882,6 @@ // CHECK_KNM_M32: #define __MOVBE__ 1 // CHECK_KNM_M32: #define __PCLMUL__ 1 // CHECK_KNM_M32: #define __POPCNT__ 1 -// CHECK_KNM_M32: #define __PREFETCHWT1__ 1 // CHECK_KNM_M32: #define __PRFCHW__ 1 // CHECK_KNM_M32: #define __RDRND__ 1 // CHECK_KNM_M32: #define __SSE2__ 1 @@ -911,9 +902,7 @@ // CHECK_KNM_M64: #define __AES__ 1 // CHECK_KNM_M64: #define __AVX2__ 1 // CHECK_KNM_M64: #define __AVX512CD__ 1 -// CHECK_KNM_M64: #define __AVX512ER__ 1 // CHECK_KNM_M64: #define __AVX512F__ 1 -// CHECK_KNM_M64: #define __AVX512PF__ 1 // CHECK_KNM_M64: #define __AVX512VPOPCNTDQ__ 1 // CHECK_KNM_M64: #define __AVX__ 1 // CHECK_KNM_M64: #define __BMI2__ 1 @@ -927,7 +916,6 @@ // CHECK_KNM_M64: #define __MOVBE__ 1 // CHECK_KNM_M64: #define __PCLMUL__ 1 // CHECK_KNM_M64: #define __POPCNT__ 1 -// CHECK_KNM_M64: #define __PREFETCHWT1__ 1 // CHECK_KNM_M64: #define __PRFCHW__ 1 // CHECK_KNM_M64: #define __RDRND__ 1 // CHECK_KNM_M64: #define __SSE2_MATH__ 1 diff --git a/clang/test/Preprocessor/stdc-ms-extension.cpp b/clang/test/Preprocessor/stdc-ms-extension.cpp new file mode 100644 index 0000000000000..6e9fa6055306e --- /dev/null +++ b/clang/test/Preprocessor/stdc-ms-extension.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cl /TC /dev/null /E -Xclang -dM 2> /dev/null | FileCheck -match-full-lines %s --check-prefix=NOSTDC +// RUN: %clang_cl /TC /dev/null /E -Xclang -dM /Zc:__STDC__ 2> /dev/null | FileCheck -match-full-lines %s --check-prefix=YESSTDC +// __STDC__ should never be defined in C++ mode with fms-compatibility. +// RUN: %clang_cl /dev/null /E -Xclang -dM 2>&1 | FileCheck %s --check-prefix=NOSTDC +// RUN: %clang_cl /dev/null /E -Xclang -dM /Zc:__STDC__ 2>&1 | FileCheck %s --check-prefix=ZCSTDCIGNORED +// YESSTDC: #define __STDC__ 1 +// NOSTDC-NOT: #define __STDC__ 1 +// ZCSTDCIGNORED-NOT: #define __STDC__ 1 +// ZCSTDCIGNORED: argument unused during compilation diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index 57104c9e7a500..7567267be26b4 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -90,38 +90,6 @@ // AVX512CD: #define __SSE__ 1 // AVX512CD: #define __SSSE3__ 1 -// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512er -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512ER %s - -// AVX512ER: #define __AVX2__ 1 -// AVX512ER: #define __AVX512ER__ 1 -// AVX512ER: #define __AVX512F__ 1 -// AVX512ER: #define __AVX__ 1 -// AVX512ER: #define __EVEX512__ 1 -// AVX512ER: #define __SSE2_MATH__ 1 -// AVX512ER: #define __SSE2__ 1 -// AVX512ER: #define __SSE3__ 1 -// AVX512ER: #define __SSE4_1__ 1 -// AVX512ER: #define __SSE4_2__ 1 -// AVX512ER: #define __SSE_MATH__ 1 -// AVX512ER: #define __SSE__ 1 -// AVX512ER: #define __SSSE3__ 1 - -// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512pf -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512PF %s - -// AVX512PF: #define __AVX2__ 1 -// AVX512PF: #define __AVX512F__ 1 -// AVX512PF: #define __AVX512PF__ 1 -// AVX512PF: #define __AVX__ 1 -// AVX512PF: #define __EVEX512__ 1 -// AVX512PF: #define __SSE2_MATH__ 1 -// AVX512PF: #define __SSE2__ 1 -// AVX512PF: #define __SSE3__ 1 -// AVX512PF: #define __SSE4_1__ 1 -// AVX512PF: #define __SSE4_2__ 1 -// AVX512PF: #define __SSE_MATH__ 1 -// AVX512PF: #define __SSE__ 1 -// AVX512PF: #define __SSSE3__ 1 - // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512dq -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512DQ %s // AVX512DQ: #define __AVX2__ 1 @@ -171,22 +139,6 @@ // AVX512VL: #define __SSE__ 1 // AVX512VL: #define __SSSE3__ 1 -// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512pf -mno-avx512f -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512F2 %s - -// AVX512F2: #define __AVX2__ 1 -// AVX512F2-NOT: #define __AVX512F__ 1 -// AVX512F2-NOT: #define __AVX512PF__ 1 -// AVX512F2-NOT: #define __EVEX512__ 1 -// AVX512F2: #define __AVX__ 1 -// AVX512F2: #define __SSE2_MATH__ 1 -// AVX512F2: #define __SSE2__ 1 -// AVX512F2: #define __SSE3__ 1 -// AVX512F2: #define __SSE4_1__ 1 -// AVX512F2: #define __SSE4_2__ 1 -// AVX512F2: #define __SSE_MATH__ 1 -// AVX512F2: #define __SSE__ 1 -// AVX512F2: #define __SSSE3__ 1 - // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512ifma -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512IFMA %s // AVX512IFMA: #define __AVX2__ 1 @@ -640,14 +592,12 @@ // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512f -mno-avx512f -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOEVEX512 %s // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512cd -mno-avx512f -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOEVEX512 %s -// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512er -mno-avx512f -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOEVEX512 %s // NOEVEX512-NOT: #define __AVX512F__ 1 // NOEVEX512-NOT: #define __EVEX256__ 1 // NOEVEX512-NOT: #define __EVEX512__ 1 // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512f -mno-evex512 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512NOEVEX512 %s // RUN: %clang -target i386-unknown-unknown -march=atom -mavx512cd -mno-evex512 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512NOEVEX512 %s -// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512er -mno-evex512 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512NOEVEX512 %s // AVX512NOEVEX512: #define __AVX512F__ 1 // AVX512NOEVEX512-NOT: #define __EVEX256__ 1 // AVX512NOEVEX512-NOT: #define __EVEX512__ 1 diff --git a/clang/test/Profile/misexpect-branch.c b/clang/test/Profile/misexpect-branch.c index ce46b46880611..5c4394405e178 100644 --- a/clang/test/Profile/misexpect-branch.c +++ b/clang/test/Profile/misexpect-branch.c @@ -26,10 +26,10 @@ int buzz(); const int inner_loop = 100; const int outer_loop = 2000; -int bar() { // imprecise-warning-re {{Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions.}} +int bar() { // imprecise-warning-re {{potential performance regression from use of __builtin_expect(): annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions}} int rando = buzz(); int x = 0; - if (likely(rando % (outer_loop * inner_loop) == 0)) { // exact-warning-re {{Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions.}} + if (likely(rando % (outer_loop * inner_loop) == 0)) { // exact-warning-re {{potential performance regression from use of __builtin_expect(): annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions}} x = baz(rando); } else { x = foo(50); @@ -37,10 +37,10 @@ int bar() { // imprecise-warning-re {{Potential performance regression from use return x; } -int fizz() { // imprecise-warning-re {{Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions.}} +int fizz() { // imprecise-warning-re {{potential performance regression from use of __builtin_expect(): annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions}} int rando = buzz(); int x = 0; - if (unlikely(rando % (outer_loop * inner_loop) == 0)) { // exact-warning-re {{Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions.}} + if (unlikely(rando % (outer_loop * inner_loop) == 0)) { // exact-warning-re {{potential performance regression from use of __builtin_expect(): annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions}} x = baz(rando); } else { x = foo(50); diff --git a/clang/test/Profile/misexpect-switch-default.c b/clang/test/Profile/misexpect-switch-default.c index 033490e558e6a..cd337b9430171 100644 --- a/clang/test/Profile/misexpect-switch-default.c +++ b/clang/test/Profile/misexpect-switch-default.c @@ -20,7 +20,7 @@ int main() { int j; for (j = 0; j < outer_loop * inner_loop; ++j) { unsigned condition = rand() % 5; - switch (__builtin_expect(condition, 6)) { // expected-warning-re {{Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions.}} + switch (__builtin_expect(condition, 6)) { // expected-warning-re {{potential performance regression from use of __builtin_expect(): annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions}} case 0: val += sum(arry, arry_size); break; diff --git a/clang/test/Profile/misexpect-switch.c b/clang/test/Profile/misexpect-switch.c index 8ca8a155c74a7..84a7174f635fd 100644 --- a/clang/test/Profile/misexpect-switch.c +++ b/clang/test/Profile/misexpect-switch.c @@ -20,7 +20,7 @@ int main() { for (j = 0; j < outer_loop; ++j) { for (k = 0; k < inner_loop; ++k) { unsigned condition = rand() % 10000; - switch (__builtin_expect(condition, 0)) { // expected-warning-re {{Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions.}} + switch (__builtin_expect(condition, 0)) { // expected-warning-re {{potential performance regression from use of __builtin_expect(): annotation was correct on {{.+}}% ({{[0-9]+ / [0-9]+}}) of profiled executions}} case 0: val += sum(arry, arry_size); break; diff --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c index 1d36667d6cf40..2024b81ce6aec 100644 --- a/clang/test/Sema/atomic-ops.c +++ b/clang/test/Sema/atomic-ops.c @@ -639,6 +639,38 @@ void memory_checks(_Atomic(int) *Ap, int *p, int val) { (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, -1); // expected-warning {{memory order argument to atomic operation is invalid}} } +struct Z { + char z[]; +}; + +void zeroSizeArgError(struct Z *a, struct Z *b, struct Z *c) { + __atomic_exchange(b, b, c, memory_order_relaxed); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_exchange(b, b, c, memory_order_acq_rel); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_exchange(b, b, c, memory_order_acquire); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_exchange(b, b, c, memory_order_consume); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_exchange(b, b, c, memory_order_release); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_exchange(b, b, c, memory_order_seq_cst); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_load(a, b, memory_order_relaxed); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_load(a, b, memory_order_acq_rel); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_load(a, b, memory_order_acquire); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_load(a, b, memory_order_consume); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_load(a, b, memory_order_release); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_load(a, b, memory_order_seq_cst); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_store(a, b, memory_order_relaxed); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_store(a, b, memory_order_acq_rel); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_store(a, b, memory_order_acquire); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_store(a, b, memory_order_consume); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_store(a, b, memory_order_release); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_store(a, b, memory_order_seq_cst); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_compare_exchange(a, b, c, 0, memory_order_relaxed, memory_order_relaxed); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_compare_exchange(a, b, c, 0, memory_order_acq_rel, memory_order_acq_rel); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_compare_exchange(a, b, c, 0, memory_order_acquire, memory_order_acquire); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_compare_exchange(a, b, c, 0, memory_order_consume, memory_order_consume); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_compare_exchange(a, b, c, 0, memory_order_release, memory_order_release); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + __atomic_compare_exchange(a, b, c, 0, memory_order_seq_cst, memory_order_seq_cst); // expected-error {{address argument to atomic builtin must be a pointer to a non-zero-sized object}} + +} + void nullPointerWarning(void) { volatile _Atomic(int) vai; _Atomic(int) ai; diff --git a/clang/test/Sema/attr-assume.c b/clang/test/Sema/attr-assume.c deleted file mode 100644 index 98deffa3a7460..0000000000000 --- a/clang/test/Sema/attr-assume.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s - -void f1(void) __attribute__((assume(3))); // expected-error {{expected string literal as argument of 'assume' attribute}} -void f2(void) __attribute__((assume(int))); // expected-error {{expected string literal as argument of 'assume' attribute}} -void f3(void) __attribute__((assume(for))); // expected-error {{expected string literal as argument of 'assume' attribute}} -void f4(void) __attribute__((assume("QQQQ"))); // expected-warning {{unknown assumption string 'QQQQ'; attribute is potentially ignored}} -void f5(void) __attribute__((assume("omp_no_openmp"))); -void f6(void) __attribute__((assume("omp_noopenmp"))); // expected-warning {{unknown assumption string 'omp_noopenmp' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp'?}} -void f7(void) __attribute__((assume("omp_no_openmp_routine"))); // expected-warning {{unknown assumption string 'omp_no_openmp_routine' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp_routines'?}} -void f8(void) __attribute__((assume("omp_no_openmp1"))); // expected-warning {{unknown assumption string 'omp_no_openmp1' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp'?}} -void f9(void) __attribute__((assume("omp_no_openmp", "omp_no_openmp"))); // expected-error {{'assume' attribute takes one argument}} - -int g1 __attribute__((assume(0))); // expected-error {{expected string literal as argument of 'assume' attribute}} -int g2 __attribute__((assume("omp_no_openmp"))); // expected-warning {{'assume' attribute only applies to functions and Objective-C methods}} diff --git a/clang/test/Sema/attr-counted-by-late-parsed-off.c b/clang/test/Sema/attr-counted-by-late-parsed-off.c new file mode 100644 index 0000000000000..34f51d10c0838 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-late-parsed-off.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -DNEEDS_LATE_PARSING -fno-experimental-late-parse-attributes -fsyntax-only -verify %s +// RUN: %clang_cc1 -DNEEDS_LATE_PARSING -fsyntax-only -verify %s + +// RUN: %clang_cc1 -UNEEDS_LATE_PARSING -fno-experimental-late-parse-attributes -fsyntax-only -verify=ok %s +// RUN: %clang_cc1 -UNEEDS_LATE_PARSING -fsyntax-only -verify=ok %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct size_known { int dummy; }; + +#ifdef NEEDS_LATE_PARSING +struct on_decl { + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known *buf __counted_by(count); + int count; +}; + +#else + +// ok-no-diagnostics +struct on_decl { + int count; + struct size_known *buf __counted_by(count); +}; + +#endif diff --git a/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c b/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c new file mode 100644 index 0000000000000..9ff3b080f6576 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c @@ -0,0 +1,254 @@ +// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct size_unknown; +struct size_known { + int field; +}; + +typedef void(*fn_ptr_ty)(void); + +//============================================================================== +// __counted_by on struct member pointer in decl attribute position +//============================================================================== + +struct on_member_pointer_complete_ty { + struct size_known * buf __counted_by(count); + int count; +}; + +struct on_member_pointer_incomplete_ty { + struct size_unknown * buf __counted_by(count); // expected-error{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} + int count; +}; + +struct on_member_pointer_const_incomplete_ty { + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} + const struct size_unknown * buf __counted_by(count); + int count; +}; + +struct on_member_pointer_void_ty { + void* buf __counted_by(count); // expected-error{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}} + int count; +}; + +struct on_member_pointer_fn_ptr_ty { + // buffer of `count` function pointers is allowed + void (**fn_ptr)(void) __counted_by(count); + int count; +}; + + +struct on_member_pointer_fn_ptr_ty_ptr_ty { + // buffer of `count` function pointers is allowed + fn_ptr_ty* fn_ptr __counted_by(count); + int count; +}; + +struct on_member_pointer_fn_ty { + // buffer of `count` functions is not allowed + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}} + void (*fn_ptr)(void) __counted_by(count); + int count; +}; + +struct on_member_pointer_fn_ptr_ty_ty { + // buffer of `count` functions is not allowed + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}} + fn_ptr_ty fn_ptr __counted_by(count); + int count; +}; + +struct has_unannotated_vla { + int count; + int buffer[]; +}; + +struct on_member_pointer_struct_with_vla { + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_unannotated_vla' is a struct type with a flexible array member}} + struct has_unannotated_vla* objects __counted_by(count); + int count; +}; + +struct has_annotated_vla { + int count; + int buffer[] __counted_by(count); +}; + +// Currently prevented because computing the size of `objects` at runtime would +// require an O(N) walk of `objects` to take into account the length of the VLA +// in each struct instance. +struct on_member_pointer_struct_with_annotated_vla { + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_annotated_vla' is a struct type with a flexible array member}} + struct has_annotated_vla* objects __counted_by(count); + int count; +}; + +struct on_pointer_anon_buf { + // TODO: Support referring to parent scope + struct { + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known *buf __counted_by(count); + }; + int count; +}; + +struct on_pointer_anon_count { + struct size_known *buf __counted_by(count); + struct { + int count; + }; +}; + +//============================================================================== +// __counted_by on struct member pointer in type attribute position +//============================================================================== +// TODO: Correctly parse counted_by as a type attribute. Currently it is parsed +// as a declaration attribute and is **not** late parsed resulting in the `count` +// field being unavailable. + +struct on_member_pointer_complete_ty_ty_pos { + // TODO: Allow this + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known *__counted_by(count) buf; + int count; +}; + +struct on_member_pointer_incomplete_ty_ty_pos { + // TODO: Allow this + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_unknown * __counted_by(count) buf; + int count; +}; + +struct on_member_pointer_const_incomplete_ty_ty_pos { + // TODO: Allow this + // expected-error@+1{{use of undeclared identifier 'count'}} + const struct size_unknown * __counted_by(count) buf; + int count; +}; + +struct on_member_pointer_void_ty_ty_pos { + // TODO: This should fail because the attribute is + // on a pointer with the pointee being an incomplete type. + // expected-error@+1{{use of undeclared identifier 'count'}} + void *__counted_by(count) buf; + int count; +}; + +// - + +struct on_member_pointer_fn_ptr_ty_pos { + // TODO: buffer of `count` function pointers should be allowed + // but fails because this isn't late parsed. + // expected-error@+1{{use of undeclared identifier 'count'}} + void (** __counted_by(count) fn_ptr)(void); + int count; +}; + +struct on_member_pointer_fn_ptr_ty_ptr_ty_pos { + // TODO: buffer of `count` function pointers should be allowed + // but fails because this isn't late parsed. + // expected-error@+1{{use of undeclared identifier 'count'}} + fn_ptr_ty* __counted_by(count) fn_ptr; + int count; +}; + +struct on_member_pointer_fn_ty_ty_pos { + // TODO: This should fail because the attribute is + // on a pointer with the pointee being a function type. + // expected-error@+1{{use of undeclared identifier 'count'}} + void (* __counted_by(count) fn_ptr)(void); + int count; +}; + +struct on_member_pointer_fn_ptr_ty_ty_pos { + // TODO: buffer of `count` function pointers should be allowed + // expected-error@+1{{use of undeclared identifier 'count'}} + void (** __counted_by(count) fn_ptr)(void); + int count; +}; + +struct on_member_pointer_fn_ptr_ty_typedef_ty_pos { + // TODO: This should fail because the attribute is + // on a pointer with the pointee being a function type. + // expected-error@+1{{use of undeclared identifier 'count'}} + fn_ptr_ty __counted_by(count) fn_ptr; + int count; +}; + +struct on_member_pointer_fn_ptr_ty_ty_pos_inner { + // TODO: This should fail because the attribute is + // on a pointer with the pointee being a function type. + // expected-error@+1{{use of undeclared identifier 'count'}} + void (* __counted_by(count) * fn_ptr)(void); + int count; +}; + +struct on_member_pointer_struct_with_vla_ty_pos { + // TODO: This should fail because the attribute is + // on a pointer with the pointee being a struct type with a VLA. + // expected-error@+1{{use of undeclared identifier 'count'}} + struct has_unannotated_vla *__counted_by(count) objects; + int count; +}; + +struct on_member_pointer_struct_with_annotated_vla_ty_pos { + // TODO: This should fail because the attribute is + // on a pointer with the pointee being a struct type with a VLA. + // expected-error@+1{{use of undeclared identifier 'count'}} + struct has_annotated_vla* __counted_by(count) objects; + int count; +}; + +struct on_nested_pointer_inner { + // TODO: This should be disallowed because in the `-fbounds-safety` model + // `__counted_by` can only be nested when used in function parameters. + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known *__counted_by(count) *buf; + int count; +}; + +struct on_nested_pointer_outer { + // TODO: Allow this + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known **__counted_by(count) buf; + int count; +}; + +struct on_pointer_anon_buf_ty_pos { + struct { + // TODO: Support referring to parent scope + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known * __counted_by(count) buf; + }; + int count; +}; + +struct on_pointer_anon_count_ty_pos { + // TODO: Allow this + // expected-error@+1{{use of undeclared identifier 'count'}} + struct size_known *__counted_by(count) buf; + struct { + int count; + }; +}; + +//============================================================================== +// __counted_by on struct non-pointer members +//============================================================================== + +struct on_pod_ty { + // expected-error@+1{{'counted_by' only applies to pointers or C99 flexible array members}} + int wrong_ty __counted_by(count); + int count; +}; + +struct on_void_ty { + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{field has incomplete type 'void'}} + void wrong_ty __counted_by(count); + int count; +}; diff --git a/clang/test/Sema/attr-counted-by-struct-ptrs-sizeless-types.c b/clang/test/Sema/attr-counted-by-struct-ptrs-sizeless-types.c new file mode 100644 index 0000000000000..9b0f2eafb13c2 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-struct-ptrs-sizeless-types.c @@ -0,0 +1,17 @@ +// __SVInt8_t is specific to ARM64 so specify that in the target triple +// RUN: %clang_cc1 -triple arm64-apple-darwin -fsyntax-only -verify %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct on_sizeless_pointee_ty { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because '__SVInt8_t' is a sizeless type}} + __SVInt8_t* member __counted_by(count); +}; + +struct on_sizeless_ty { + int count; + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{field has sizeless type '__SVInt8_t'}} + __SVInt8_t member __counted_by(count); +}; diff --git a/clang/test/Sema/attr-counted-by-struct-ptrs.c b/clang/test/Sema/attr-counted-by-struct-ptrs.c new file mode 100644 index 0000000000000..cd2bfe36938b2 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-struct-ptrs.c @@ -0,0 +1,224 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct size_unknown; +struct size_known { + int field; +}; + +typedef void(*fn_ptr_ty)(void); + +//============================================================================== +// __counted_by on struct member pointer in decl attribute position +//============================================================================== + +struct on_member_pointer_complete_ty { + int count; + struct size_known * buf __counted_by(count); +}; + +struct on_member_pointer_incomplete_ty { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} + struct size_unknown * buf __counted_by(count); +}; + +struct on_member_pointer_const_incomplete_ty { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} + const struct size_unknown * buf __counted_by(count); +}; + +struct on_member_pointer_void_ty { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}} + void* buf __counted_by(count); +}; + +struct on_member_pointer_fn_ptr_ty { + int count; + // buffer of `count` function pointers is allowed + void (**fn_ptr)(void) __counted_by(count); +}; + +struct on_member_pointer_fn_ptr_ty_ptr_ty { + int count; + // buffer of `count` function pointers is allowed + fn_ptr_ty* fn_ptr __counted_by(count); +}; + +struct on_member_pointer_fn_ty { + int count; + // buffer of `count` functions is not allowed + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}} + void (*fn_ptr)(void) __counted_by(count); +}; + +struct on_member_pointer_fn_ptr_ty_ty { + int count; + // buffer of `count` functions is not allowed + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}} + fn_ptr_ty fn_ptr __counted_by(count); +}; + +struct has_unannotated_vla { + int count; + int buffer[]; +}; + +struct on_member_pointer_struct_with_vla { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_unannotated_vla' is a struct type with a flexible array member}} + struct has_unannotated_vla* objects __counted_by(count); +}; + +struct has_annotated_vla { + int count; + int buffer[] __counted_by(count); +}; + +// Currently prevented because computing the size of `objects` at runtime would +// require an O(N) walk of `objects` to take into account the length of the VLA +// in each struct instance. +struct on_member_pointer_struct_with_annotated_vla { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_annotated_vla' is a struct type with a flexible array member}} + struct has_annotated_vla* objects __counted_by(count); +}; + +struct on_pointer_anon_buf { + int count; + struct { + struct size_known *buf __counted_by(count); + }; +}; + +struct on_pointer_anon_count { + struct { + int count; + }; + struct size_known *buf __counted_by(count); +}; + +//============================================================================== +// __counted_by on struct member pointer in type attribute position +//============================================================================== +// TODO: Correctly parse counted_by as a type attribute. Currently it is parsed +// as a declaration attribute + +struct on_member_pointer_complete_ty_ty_pos { + int count; + struct size_known *__counted_by(count) buf; +}; + +struct on_member_pointer_incomplete_ty_ty_pos { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} + struct size_unknown * __counted_by(count) buf; +}; + +struct on_member_pointer_const_incomplete_ty_ty_pos { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} + const struct size_unknown * __counted_by(count) buf; +}; + +struct on_member_pointer_void_ty_ty_pos { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}} + void *__counted_by(count) buf; +}; + +// - + +struct on_member_pointer_fn_ptr_ty_pos { + int count; + // buffer of `count` function pointers is allowed + void (** __counted_by(count) fn_ptr)(void); +}; + +struct on_member_pointer_fn_ptr_ty_ptr_ty_pos { + int count; + // buffer of `count` function pointers is allowed + fn_ptr_ty* __counted_by(count) fn_ptr; +}; + +struct on_member_pointer_fn_ty_ty_pos { + int count; + // buffer of `count` functions is not allowed + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}} + void (* __counted_by(count) fn_ptr)(void); +}; + +struct on_member_pointer_fn_ptr_ty_ty_pos { + int count; + // buffer of `count` functions is not allowed + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}} + fn_ptr_ty __counted_by(count) fn_ptr; +}; + +// TODO: This should be forbidden but isn't due to counted_by being treated +// as a declaration attribute. +struct on_member_pointer_fn_ptr_ty_ty_pos_inner { + int count; + void (* __counted_by(count) * fn_ptr)(void); +}; + +struct on_member_pointer_struct_with_vla_ty_pos { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_unannotated_vla' is a struct type with a flexible array member}} + struct has_unannotated_vla *__counted_by(count) objects; +}; + +// Currently prevented because computing the size of `objects` at runtime would +// require an O(N) walk of `objects` to take into account the length of the VLA +// in each struct instance. +struct on_member_pointer_struct_with_annotated_vla_ty_pos { + int count; + // expected-error@+1{{counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_annotated_vla' is a struct type with a flexible array member}} + struct has_annotated_vla* __counted_by(count) objects; +}; + +struct on_nested_pointer_inner { + // TODO: This should be disallowed because in the `-fbounds-safety` model + // `__counted_by` can only be nested when used in function parameters. + int count; + struct size_known *__counted_by(count) *buf; +}; + +struct on_nested_pointer_outer { + int count; + struct size_known **__counted_by(count) buf; +}; + +struct on_pointer_anon_buf_ty_pos { + int count; + struct { + struct size_known * __counted_by(count) buf; + }; +}; + +struct on_pointer_anon_count_ty_pos { + struct { + int count; + }; + struct size_known *__counted_by(count) buf; +}; + +//============================================================================== +// __counted_by on struct non-pointer members +//============================================================================== + +struct on_pod_ty { + int count; + // expected-error@+1{{'counted_by' only applies to pointers or C99 flexible array members}} + int wrong_ty __counted_by(count); +}; + +struct on_void_ty { + int count; + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{field has incomplete type 'void'}} + void wrong_ty __counted_by(count); +}; diff --git a/clang/test/Sema/attr-counted-by-vla-sizeless-types.c b/clang/test/Sema/attr-counted-by-vla-sizeless-types.c new file mode 100644 index 0000000000000..31c0007501c48 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-vla-sizeless-types.c @@ -0,0 +1,11 @@ +// __SVInt8_t is specific to ARM64 so specify that in the target triple +// RUN: %clang_cc1 -triple arm64-apple-darwin -fsyntax-only -verify %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct on_sizeless_elt_ty { + int count; + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{array has sizeless element type '__SVInt8_t'}} + __SVInt8_t arr[] __counted_by(count); +}; diff --git a/clang/test/Sema/attr-counted-by-vla.c b/clang/test/Sema/attr-counted-by-vla.c new file mode 100644 index 0000000000000..b25f719f3b95a --- /dev/null +++ b/clang/test/Sema/attr-counted-by-vla.c @@ -0,0 +1,196 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +struct bar; + +struct not_found { + int count; + struct bar *fam[] __counted_by(bork); // expected-error {{use of undeclared identifier 'bork'}} +}; + +struct no_found_count_not_in_substruct { + unsigned long flags; + unsigned char count; // expected-note {{'count' declared here}} + struct A { + int dummy; + int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} + } a; +}; + +struct not_found_count_not_in_unnamed_substruct { + unsigned char count; // expected-note {{'count' declared here}} + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} + } a; +}; + +struct not_found_count_not_in_unnamed_substruct_2 { + struct { + unsigned char count; // expected-note {{'count' declared here}} + }; + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} + } a; +}; + +struct not_found_count_in_other_unnamed_substruct { + struct { + unsigned char count; + } a1; + + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} + }; +}; + +struct not_found_count_in_other_substruct { + struct _a1 { + unsigned char count; + } a1; + + struct { + int dummy; + int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} + }; +}; + +struct not_found_count_in_other_substruct_2 { + struct _a2 { + unsigned char count; + } a2; + + int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} +}; + +struct not_found_suggest { + int bork; + struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'}} +}; + +int global; // expected-note {{'global' declared here}} + +struct found_outside_of_struct { + int bork; + struct bar *fam[] __counted_by(global); // expected-error {{field 'global' in 'counted_by' not inside structure}} +}; + +struct self_referrential { + int bork; + struct bar *self[] __counted_by(self); // expected-error {{use of undeclared identifier 'self'}} +}; + +struct non_int_count { + double dbl_count; + struct bar *fam[] __counted_by(dbl_count); // expected-error {{'counted_by' requires a non-boolean integer type argument}} +}; + +struct array_of_ints_count { + int integers[2]; + struct bar *fam[] __counted_by(integers); // expected-error {{'counted_by' requires a non-boolean integer type argument}} +}; + +struct not_a_fam { + int count; + // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct bar' is an incomplete type}} + struct bar *non_fam __counted_by(count); +}; + +struct not_a_c99_fam { + int count; + struct bar *non_c99_fam[0] __counted_by(count); // expected-error {{'counted_by' on arrays only applies to C99 flexible array members}} +}; + +struct annotated_with_anon_struct { + unsigned long flags; + struct { + unsigned char count; + int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'}} + }; +}; + +//============================================================================== +// __counted_by on a struct VLA with element type that has unknown size +//============================================================================== + +struct size_unknown; // expected-note 2{{forward declaration of 'struct size_unknown'}} +struct on_member_arr_incomplete_ty_ty_pos { + int count; + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{array has incomplete element type 'struct size_unknown'}} + struct size_unknown buf[] __counted_by(count); +}; + +struct on_member_arr_incomplete_const_ty_ty_pos { + int count; + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{array has incomplete element type 'const struct size_unknown'}} + const struct size_unknown buf[] __counted_by(count); +}; + +struct on_member_arr_void_ty_ty_pos { + int count; + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{array has incomplete element type 'void'}} + void buf[] __counted_by(count); +}; + +typedef void(fn_ty)(int); + +struct on_member_arr_fn_ptr_ty { + int count; + // An Array of function pointers is allowed + fn_ty* buf[] __counted_by(count); +}; + +struct on_member_arr_fn_ty { + int count; + // An array of functions is not allowed. + // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} + // expected-error@+1{{'buf' declared as array of functions of type 'fn_ty' (aka 'void (int)')}} + fn_ty buf[] __counted_by(count); +}; + + +// `buffer_of_structs_with_unnannotated_vla`, +// `buffer_of_structs_with_annotated_vla`, and +// `buffer_of_const_structs_with_annotated_vla` are currently prevented because +// computing the size of `Arr` at runtime would require an O(N) walk of `Arr` +// elements to take into account the length of the VLA in each struct instance. + +struct has_unannotated_VLA { + int count; + char buffer[]; +}; + +struct has_annotated_VLA { + int count; + char buffer[] __counted_by(count); +}; + +struct buffer_of_structs_with_unnannotated_vla { + int count; + // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**. + // expected-warning@+1{{'counted_by' should not be applied to an array with element of unknown size because 'struct has_unannotated_VLA' is a struct type with a flexible array member. This will be an error in a future compiler version}} + struct has_unannotated_VLA Arr[] __counted_by(count); +}; + + +struct buffer_of_structs_with_annotated_vla { + int count; + // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**. + // expected-warning@+1{{'counted_by' should not be applied to an array with element of unknown size because 'struct has_annotated_VLA' is a struct type with a flexible array member. This will be an error in a future compiler version}} + struct has_annotated_VLA Arr[] __counted_by(count); +}; + +struct buffer_of_const_structs_with_annotated_vla { + int count; + // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**. + // Make sure the `const` qualifier is printed when printing the element type. + // expected-warning@+1{{'counted_by' should not be applied to an array with element of unknown size because 'const struct has_annotated_VLA' is a struct type with a flexible array member. This will be an error in a future compiler version}} + const struct has_annotated_VLA Arr[] __counted_by(count); +}; + diff --git a/clang/test/Sema/attr-counted-by.c b/clang/test/Sema/attr-counted-by.c deleted file mode 100644 index d5d4ebf557392..0000000000000 --- a/clang/test/Sema/attr-counted-by.c +++ /dev/null @@ -1,112 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -#define __counted_by(f) __attribute__((counted_by(f))) - -struct bar; - -struct not_found { - int count; - struct bar *fam[] __counted_by(bork); // expected-error {{use of undeclared identifier 'bork'}} -}; - -struct no_found_count_not_in_substruct { - unsigned long flags; - unsigned char count; // expected-note {{'count' declared here}} - struct A { - int dummy; - int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} - } a; -}; - -struct not_found_count_not_in_unnamed_substruct { - unsigned char count; // expected-note {{'count' declared here}} - struct { - int dummy; - int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} - } a; -}; - -struct not_found_count_not_in_unnamed_substruct_2 { - struct { - unsigned char count; // expected-note {{'count' declared here}} - }; - struct { - int dummy; - int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the flexible array}} - } a; -}; - -struct not_found_count_in_other_unnamed_substruct { - struct { - unsigned char count; - } a1; - - struct { - int dummy; - int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} - }; -}; - -struct not_found_count_in_other_substruct { - struct _a1 { - unsigned char count; - } a1; - - struct { - int dummy; - int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} - }; -}; - -struct not_found_count_in_other_substruct_2 { - struct _a2 { - unsigned char count; - } a2; - - int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}} -}; - -struct not_found_suggest { - int bork; - struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'}} -}; - -int global; // expected-note {{'global' declared here}} - -struct found_outside_of_struct { - int bork; - struct bar *fam[] __counted_by(global); // expected-error {{field 'global' in 'counted_by' not inside structure}} -}; - -struct self_referrential { - int bork; - struct bar *self[] __counted_by(self); // expected-error {{use of undeclared identifier 'self'}} -}; - -struct non_int_count { - double dbl_count; - struct bar *fam[] __counted_by(dbl_count); // expected-error {{'counted_by' requires a non-boolean integer type argument}} -}; - -struct array_of_ints_count { - int integers[2]; - struct bar *fam[] __counted_by(integers); // expected-error {{'counted_by' requires a non-boolean integer type argument}} -}; - -struct not_a_fam { - int count; - struct bar *non_fam __counted_by(count); // expected-error {{'counted_by' only applies to C99 flexible array members}} -}; - -struct not_a_c99_fam { - int count; - struct bar *non_c99_fam[0] __counted_by(count); // expected-error {{'counted_by' only applies to C99 flexible array members}} -}; - -struct annotated_with_anon_struct { - unsigned long flags; - struct { - unsigned char count; - int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'}} - }; -}; diff --git a/clang/test/Sema/attr-objc-bridge-related.m b/clang/test/Sema/attr-objc-bridge-related.m index 7b2e3e5df3fe5..6c7fb2588dbc9 100644 --- a/clang/test/Sema/attr-objc-bridge-related.m +++ b/clang/test/Sema/attr-objc-bridge-related.m @@ -3,5 +3,5 @@ struct [[clang::objc_bridge_related(NSParagraphStyle,,)]] TestBridgedRef; struct [[clang::objc_bridge_related(NSColor,colorWithCGColor:,CGColor)]] CGColorRefOk; -struct [[clang::objc_bridge_related(,colorWithCGColor:,CGColor)]] CGColorRef1NotOk; // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}} +struct [[clang::objc_bridge_related(,colorWithCGColor:,CGColor)]] CGColorRef1NotOk; // expected-error {{expected a related Objective-C class name, e.g., 'NSColor'}} struct [[clang::objc_bridge_related(NSColor,colorWithCGColor::,CGColor)]] CGColorRef3NotOk; // expected-error {{expected a class method selector with single argument, e.g., 'colorWithCGColor:'}} diff --git a/clang/test/Sema/builtin-assume.c b/clang/test/Sema/builtin-assume.c index 932fb5c973eb0..21d62d8fd06c1 100644 --- a/clang/test/Sema/builtin-assume.c +++ b/clang/test/Sema/builtin-assume.c @@ -8,20 +8,20 @@ int ispure(int) __attribute__((pure)); int foo(int *a, int i) { #ifdef _MSC_VER __assume(i != 4); - __assume(++i > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}} - __assume(nonconst() > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}} + __assume(++i > 2); //expected-warning {{assumption is ignored because it contains (potential) side-effects}} + __assume(nonconst() > 2); //expected-warning {{assumption is ignored because it contains (potential) side-effects}} __assume(isconst() > 2); __assume(ispure(i) > 2); - __assume(ispure(++i) > 2); //expected-warning {{the argument to '__assume' has side effects that will be discarded}} + __assume(ispure(++i) > 2); //expected-warning {{assumption is ignored because it contains (potential) side-effects}} int test = sizeof(struct{char qq[(__assume(i != 5), 7)];}); #else __builtin_assume(i != 4); - __builtin_assume(++i > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} - __builtin_assume(nonconst() > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} + __builtin_assume(++i > 2); //expected-warning {{assumption is ignored because it contains (potential) side-effects}} + __builtin_assume(nonconst() > 2); //expected-warning {{assumption is ignored because it contains (potential) side-effects}} __builtin_assume(isconst() > 2); __builtin_assume(ispure(i) > 2); - __builtin_assume(ispure(++i) > 2); //expected-warning {{the argument to '__builtin_assume' has side effects that will be discarded}} + __builtin_assume(ispure(++i) > 2); //expected-warning {{assumption is ignored because it contains (potential) side-effects}} int test = sizeof(struct{char qq[(__builtin_assume(i != 5), 7)];}); // expected-warning {{variable length array}} #endif diff --git a/clang/test/Sema/builtins-x86.c b/clang/test/Sema/builtins-x86.c index cbaf7bcde871e..7d9cdce3d7894 100644 --- a/clang/test/Sema/builtins-x86.c +++ b/clang/test/Sema/builtins-x86.c @@ -106,14 +106,6 @@ __m128i test_mm_mask_i32gather_epi32(__m128i a, int const *b, __m128i c, __m128i return __builtin_ia32_gatherd_d(a, b, c, mask, 5); // expected-error {{scale argument must be 1, 2, 4, or 8}} } -void _mm512_mask_prefetch_i32gather_ps(__m512i index, __mmask16 mask, int const *addr) { - __builtin_ia32_gatherpfdps(mask, index, addr, 5, 1); // expected-error {{scale argument must be 1, 2, 4, or 8}} -} - -void _mm512_mask_prefetch_i32gather_ps_2(__m512i index, __mmask16 mask, int const *addr) { - __builtin_ia32_gatherpfdps(mask, index, addr, 1, 1); // expected-error {{argument value 1 is outside the valid range [2, 3]}} -} - __m512i test_mm512_shldi_epi64(__m512i __A, __m512i __B) { return __builtin_ia32_vpshldq512(__A, __B, 1024); // expected-error {{argument value 1024 is outside the valid range [0, 255]}} } diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c index 3bee314595291..4f843aeec24e6 100644 --- a/clang/test/Sema/builtins.c +++ b/clang/test/Sema/builtins.c @@ -277,9 +277,9 @@ void test21(const int *ptr) { } void test_ei_i42i(_BitInt(42) *ptr, int value) { - __sync_fetch_and_add(ptr, value); // expected-error {{Atomic memory operand must have a power-of-two size}} + __sync_fetch_and_add(ptr, value); // expected-error {{atomic memory operand must have a power-of-two size}} // expected-warning@+1 {{the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here}} - __sync_nand_and_fetch(ptr, value); // expected-error {{Atomic memory operand must have a power-of-two size}} + __sync_nand_and_fetch(ptr, value); // expected-error {{atomic memory operand must have a power-of-two size}} __atomic_fetch_add(ptr, 1, 0); // expected-error {{argument to atomic builtin of type '_BitInt' is not supported}} } @@ -305,9 +305,9 @@ void test_ei_ii64(int *ptr, _BitInt(64) value) { } void test_ei_i42i42(_BitInt(42) *ptr, _BitInt(42) value) { - __sync_fetch_and_add(ptr, value); // expected-error {{Atomic memory operand must have a power-of-two size}} + __sync_fetch_and_add(ptr, value); // expected-error {{atomic memory operand must have a power-of-two size}} // expected-warning@+1 {{the semantics of this intrinsic changed with GCC version 4.4 - the newer semantics are provided here}} - __sync_nand_and_fetch(ptr, value); // expected-error {{Atomic memory operand must have a power-of-two size}} + __sync_nand_and_fetch(ptr, value); // expected-error {{atomic memory operand must have a power-of-two size}} } void test_ei_i64i64(_BitInt(64) *ptr, _BitInt(64) value) { diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index ddb78696ce624..c6b1b37cef28b 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -719,7 +719,7 @@ constexpr vector4char vectorShuffleFail1 = // expected-error {{constexpr variable 'vectorShuffleFail1'\ must be initialized by a constant expression}} __builtin_shufflevector( // expected-error {{index for __builtin_shufflevector \ -not within the bounds of the input vectors; index of -1 found at position 0 not \ -permitted in a constexpr context.}} +not within the bounds of the input vectors; index of -1 found at position 0 is not \ +permitted in a constexpr context}} vector4charConst1, vector4charConst2, -1, -1, -1, -1); diff --git a/clang/test/Sema/fmv-namespace.cpp b/clang/test/Sema/fmv-namespace.cpp new file mode 100644 index 0000000000000..1c12fd66cf243 --- /dev/null +++ b/clang/test/Sema/fmv-namespace.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fsyntax-only -verify %s +// expected-no-diagnostics + +namespace Name { +int __attribute((target_version("default"))) foo() { return 0; } +} + +namespace Name { +int __attribute((target_version("sve"))) foo() { return 1; } +} + +int bar() { return Name::foo(); } diff --git a/clang/test/Sema/stmtexprs.c b/clang/test/Sema/stmtexprs.c index 708fc9abb75c0..7493bbcef363d 100644 --- a/clang/test/Sema/stmtexprs.c +++ b/clang/test/Sema/stmtexprs.c @@ -4,6 +4,6 @@ int stmtexpr_fn(void); void stmtexprs(int i) { __builtin_assume( ({ 1; }) ); // no warning about "side effects" __builtin_assume( ({ if (i) { (void)0; }; 42; }) ); // no warning about "side effects" - // expected-warning@+1 {{the argument to '__builtin_assume' has side effects that will be discarded}} + // expected-warning@+1 {{assumption is ignored because it contains (potential) side-effects}} __builtin_assume( ({ if (i) ({ stmtexpr_fn(); }); 1; }) ); } diff --git a/clang/test/Sema/x86-eval-method.c b/clang/test/Sema/x86-eval-method.c index f475b0d1b29bc..e540a59528b6d 100644 --- a/clang/test/Sema/x86-eval-method.c +++ b/clang/test/Sema/x86-eval-method.c @@ -10,9 +10,9 @@ float add1(float a, float b, float c) { return a + b + c; -} // warn-warning{{Setting the floating point evaluation method to `source` on a target without SSE is not supported.}} +} // warn-warning{{setting the floating point evaluation method to `source` on a target without SSE is not supported}} float add2(float a, float b, float c) { #pragma clang fp eval_method(source) return a + b + c; -} // warn-warning{{Setting the floating point evaluation method to `source` on a target without SSE is not supported.}} +} // warn-warning{{setting the floating point evaluation method to `source` on a target without SSE is not supported}} diff --git a/clang/test/Sema/x86_64-eval-method.c b/clang/test/Sema/x86_64-eval-method.c index dbdc1f881b4a8..fe4368a42ca12 100644 --- a/clang/test/Sema/x86_64-eval-method.c +++ b/clang/test/Sema/x86_64-eval-method.c @@ -10,4 +10,4 @@ float add2(float a, float b, float c) { #pragma clang fp eval_method(source) return a + b + c; -} // warn-warning{{Setting the floating point evaluation method to `source` on a target without SSE is not supported.}} +} // warn-warning{{setting the floating point evaluation method to `source` on a target without SSE is not supported}} diff --git a/clang/test/SemaCUDA/device-var-init.cu b/clang/test/SemaCUDA/device-var-init.cu index ee7a9e2276f2d..1555d151c2590 100644 --- a/clang/test/SemaCUDA/device-var-init.cu +++ b/clang/test/SemaCUDA/device-var-init.cu @@ -13,17 +13,17 @@ #include "Inputs/cuda-initializers.h" __shared__ int s_v_i = 1; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __device__ int d_v_f = f(); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ int s_v_f = f(); -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ int c_v_f = f(); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T s_t_i = {2}; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __device__ T d_t_i = {2}; __constant__ T c_t_i = {2}; @@ -40,175 +40,175 @@ __shared__ CGTC s_cgtc; __constant__ CGTC c_cgtc; __device__ EC d_ec_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ EC s_ec_i(3); -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ EC c_ec_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ EC d_ec_i2 = {3}; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ EC s_ec_i2 = {3}; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ EC c_ec_i2 = {3}; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ ETC d_etc_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ ETC s_etc_i(3); -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ ETC c_etc_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ ETC d_etc_i2 = {3}; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ ETC s_etc_i2 = {3}; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ ETC c_etc_i2 = {3}; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ UC d_uc; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ UC s_uc; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ UC c_uc; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ UD d_ud; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ UD s_ud; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ UD c_ud; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ ECI d_eci; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ ECI s_eci; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ ECI c_eci; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ NEC d_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NEC s_nec; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ NEC c_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ NED d_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NED s_ned; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ NED c_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ NCV d_ncv; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NCV s_ncv; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ NCV c_ncv; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ VD d_vd; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ VD s_vd; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ VD c_vd; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ NCF d_ncf; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NCF s_ncf; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ NCF c_ncf; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NCFS s_ncfs; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __device__ UTC d_utc; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ UTC s_utc; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ UTC c_utc; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ UTC d_utc_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ UTC s_utc_i(3); -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ UTC c_utc_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ NETC d_netc; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NETC s_netc; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ NETC c_netc; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ NETC d_netc_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ NETC s_netc_i(3); -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ NETC c_netc_i(3); -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ EC_I_EC1 d_ec_i_ec1; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ EC_I_EC1 s_ec_i_ec1; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ EC_I_EC1 c_ec_i_ec1; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_V_T d_t_v_t; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_V_T s_t_v_t; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_V_T c_t_v_t; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_B_NEC d_t_b_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_B_NEC s_t_b_nec; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_B_NEC c_t_b_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_F_NEC d_t_f_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_F_NEC s_t_f_nec; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_F_NEC c_t_f_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_FA_NEC d_t_fa_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_FA_NEC s_t_fa_nec; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_FA_NEC c_t_fa_nec; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_B_NED d_t_b_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_B_NED s_t_b_ned; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_B_NED c_t_b_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_F_NED d_t_f_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_F_NED s_t_f_ned; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_F_NED c_t_f_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ T_FA_NED d_t_fa_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __shared__ T_FA_NED s_t_fa_ned; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} __constant__ T_FA_NED c_t_fa_ned; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} // Verify that local variables may be static on device // side and that they conform to the initialization constraints. @@ -244,14 +244,14 @@ __device__ void df_sema() { // Same test cases as for the globals above. static __device__ int d_v_f = f(); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ int s_v_f = f(); - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ int c_v_f = f(); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T s_t_i = {2}; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __device__ T d_t_i = {2}; static __constant__ T c_t_i = {2}; @@ -260,175 +260,175 @@ __device__ void df_sema() { static __constant__ ECD c_ecd_i; static __device__ EC d_ec_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ EC s_ec_i(3); - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ EC c_ec_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ EC d_ec_i2 = {3}; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ EC s_ec_i2 = {3}; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ EC c_ec_i2 = {3}; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ ETC d_etc_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ ETC s_etc_i(3); - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ ETC c_etc_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ ETC d_etc_i2 = {3}; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ ETC s_etc_i2 = {3}; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ ETC c_etc_i2 = {3}; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ UC d_uc; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ UC s_uc; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ UC c_uc; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ UD d_ud; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ UD s_ud; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ UD c_ud; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ ECI d_eci; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ ECI s_eci; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ ECI c_eci; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ NEC d_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NEC s_nec; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ NEC c_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ NED d_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NED s_ned; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ NED c_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ NCV d_ncv; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NCV s_ncv; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ NCV c_ncv; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ VD d_vd; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ VD s_vd; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ VD c_vd; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ NCF d_ncf; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NCF s_ncf; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ NCF c_ncf; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NCFS s_ncfs; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __device__ UTC d_utc; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ UTC s_utc; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ UTC c_utc; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ UTC d_utc_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ UTC s_utc_i(3); - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ UTC c_utc_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ NETC d_netc; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NETC s_netc; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ NETC c_netc; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ NETC d_netc_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ NETC s_netc_i(3); - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ NETC c_netc_i(3); - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ EC_I_EC1 d_ec_i_ec1; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ EC_I_EC1 s_ec_i_ec1; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ EC_I_EC1 c_ec_i_ec1; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_V_T d_t_v_t; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_V_T s_t_v_t; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_V_T c_t_v_t; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_B_NEC d_t_b_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_B_NEC s_t_b_nec; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_B_NEC c_t_b_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_F_NEC d_t_f_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_F_NEC s_t_f_nec; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_F_NEC c_t_f_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_FA_NEC d_t_fa_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_FA_NEC s_t_fa_nec; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_FA_NEC c_t_fa_nec; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_B_NED d_t_b_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_B_NED s_t_b_ned; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_B_NED c_t_b_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_F_NED d_t_f_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_F_NED s_t_f_ned; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_F_NED c_t_f_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __device__ T_FA_NED d_t_fa_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} static __shared__ T_FA_NED s_t_fa_ned; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} static __constant__ T_FA_NED c_t_fa_ned; - // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} + // expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} } __host__ __device__ void hd_sema() { @@ -449,7 +449,7 @@ struct NontrivialInitializer { template __global__ void bar() { __shared__ T bad; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} for (int i = 0; i < 10; i++) { static __device__ CEEC sd_ceec; static __shared__ CEEC ss_ceec; @@ -467,7 +467,7 @@ __global__ void bar() { template <> __global__ void bar() { __shared__ NontrivialInitializer bad; -// expected-error@-1 {{initialization is not supported for __shared__ variables.}} +// expected-error@-1 {{initialization is not supported for __shared__ variables}} for (int i = 0; i < 10; i++) { static __device__ CEEC sd_ceec; static __shared__ CEEC ss_ceec; diff --git a/clang/test/SemaCUDA/function-overload.cu b/clang/test/SemaCUDA/function-overload.cu index 163648cd9a87a..4710c81763adf 100644 --- a/clang/test/SemaCUDA/function-overload.cu +++ b/clang/test/SemaCUDA/function-overload.cu @@ -469,7 +469,7 @@ int test_constexpr_overload(C2 &x, C2 &y) { // Verify no ambiguity for new operator. void *a = new int; __device__ void *b = new int; -// expected-error@-1{{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1{{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} // Verify no ambiguity for new operator. template _Tp&& f(); diff --git a/clang/test/SemaCUDA/union-init.cu b/clang/test/SemaCUDA/union-init.cu index 9e4d14a71069d..dd4b1296b713e 100644 --- a/clang/test/SemaCUDA/union-init.cu +++ b/clang/test/SemaCUDA/union-init.cu @@ -31,14 +31,14 @@ union D { __device__ B b; __device__ C c; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ D d; -// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables.}} +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} __device__ void foo() { __shared__ B b; __shared__ C c; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} __shared__ D d; - // expected-error@-1 {{initialization is not supported for __shared__ variables.}} + // expected-error@-1 {{initialization is not supported for __shared__ variables}} } diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp index 7286217b1644f..98c19975095bb 100644 --- a/clang/test/SemaCXX/MicrosoftExtensions.cpp +++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -571,11 +571,17 @@ class PR34109_class { virtual ~PR34109_class() {} }; +#if !defined(__cpp_sized_deallocation) void operator delete(void *) throw(); // expected-note@-1 {{previous declaration is here}} __declspec(dllexport) void operator delete(void *) throw(); // expected-error@-1 {{redeclaration of 'operator delete' cannot add 'dllexport' attribute}} - +#else +void operator delete(void *, unsigned int) throw(); +// expected-note@-1 {{previous declaration is here}} +__declspec(dllexport) void operator delete(void *, unsigned int) throw(); +// expected-error@-1 {{redeclaration of 'operator delete' cannot add 'dllexport' attribute}} +#endif void PR34109(int* a) { delete a; } diff --git a/clang/test/SemaCXX/addr-label-in-coroutines.cpp b/clang/test/SemaCXX/addr-label-in-coroutines.cpp index e37ee64134378..65d78636e5cdd 100644 --- a/clang/test/SemaCXX/addr-label-in-coroutines.cpp +++ b/clang/test/SemaCXX/addr-label-in-coroutines.cpp @@ -13,9 +13,9 @@ struct resumable { }; resumable f1(int &out, int *inst) { - static void* dispatch_table[] = {&&inc, // expected-error {{the GNU address of label extension is not allowed in coroutines.}} - &&suspend, // expected-error {{the GNU address of label extension is not allowed in coroutines.}} - &&stop}; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} + static void* dispatch_table[] = {&&inc, // expected-error {{the GNU address of label extension is not allowed in coroutines}} + &&suspend, // expected-error {{the GNU address of label extension is not allowed in coroutines}} + &&stop}; // expected-error {{the GNU address of label extension is not allowed in coroutines}} #define DISPATCH() goto *dispatch_table[*inst++] inc: out++; @@ -31,9 +31,9 @@ resumable f1(int &out, int *inst) { resumable f2(int &out, int *inst) { void* dispatch_table[] = {nullptr, nullptr, nullptr}; - dispatch_table[0] = &&inc; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} - dispatch_table[1] = &&suspend; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} - dispatch_table[2] = &&stop; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} + dispatch_table[0] = &&inc; // expected-error {{the GNU address of label extension is not allowed in coroutines}} + dispatch_table[1] = &&suspend; // expected-error {{the GNU address of label extension is not allowed in coroutines}} + dispatch_table[2] = &&stop; // expected-error {{the GNU address of label extension is not allowed in coroutines}} #define DISPATCH() goto *dispatch_table[*inst++] inc: out++; @@ -50,9 +50,9 @@ resumable f2(int &out, int *inst) { resumable f3(int &out, int *inst) { void* dispatch_table[] = {nullptr, nullptr, nullptr}; [&]() -> resumable { - dispatch_table[0] = &&inc; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} - dispatch_table[1] = &&suspend; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} - dispatch_table[2] = &&stop; // expected-error {{the GNU address of label extension is not allowed in coroutines.}} + dispatch_table[0] = &&inc; // expected-error {{the GNU address of label extension is not allowed in coroutines}} + dispatch_table[1] = &&suspend; // expected-error {{the GNU address of label extension is not allowed in coroutines}} + dispatch_table[2] = &&stop; // expected-error {{the GNU address of label extension is not allowed in coroutines}} #define DISPATCH() goto *dispatch_table[*inst++] inc: out++; diff --git a/clang/test/SemaCXX/attribute-pack-expansion.cpp b/clang/test/SemaCXX/attribute-pack-expansion.cpp new file mode 100644 index 0000000000000..a339e68c09648 --- /dev/null +++ b/clang/test/SemaCXX/attribute-pack-expansion.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +template +void f() __attribute((diagnose_if(vals, "message", "error"))) { // expected-error {{expression contains unexpanded parameter pack 'vals'}} + [] () __attribute((diagnose_if(vals, "message", "error"))) {}(); // expected-error {{expression contains unexpanded parameter pack 'vals'}} + [] () __attribute((diagnose_if(vals..., "message", "error"))) {}(); // expected-error {{attribute 'diagnose_if' does not support argument pack expansion}} + [] () __attribute((diagnose_if(inner, "message", "error"))) {}(); // expected-error {{expression contains unexpanded parameter pack 'inner'}} + ([] () __attribute((diagnose_if(inner, "message", "error"))) {}(), ...); // expected-error {{expression contains unexpanded parameter pack 'inner'}} \ + // expected-error {{pack expansion does not contain any unexpanded parameter packs}} + + // This is fine, so check that we're actually emitting an error + // due to the 'diagnose_if'. + ([] () __attribute((diagnose_if(vals, "foobar", "error"))) {}(), ...); // expected-error {{foobar}} expected-note {{from 'diagnose_if'}} +} + +void g() { + f<>(); + f(); + f(); // expected-note {{in instantiation of}} +} diff --git a/clang/test/SemaCXX/builtin-operator-new-delete.cpp b/clang/test/SemaCXX/builtin-operator-new-delete.cpp index 6fcff92dc0952..db15616803e37 100644 --- a/clang/test/SemaCXX/builtin-operator-new-delete.cpp +++ b/clang/test/SemaCXX/builtin-operator-new-delete.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++1z -fno-sized-deallocation -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c++03 -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c++03 -faligned-allocation -fsyntax-only -verify %s // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s diff --git a/clang/test/SemaCXX/constexpr-default-arg.cpp b/clang/test/SemaCXX/constexpr-default-arg.cpp index ec9b2927880bd..901123bfb359f 100644 --- a/clang/test/SemaCXX/constexpr-default-arg.cpp +++ b/clang/test/SemaCXX/constexpr-default-arg.cpp @@ -32,8 +32,8 @@ void test_default_arg2() { } // Check that multiple CXXDefaultInitExprs don't cause an assertion failure. -struct A { int &&r = 0; }; // expected-note 2{{default member initializer}} +struct A { int &&r = 0; }; struct B { A x, y; }; -B b = {}; // expected-warning 2{{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported}} +B b = {}; // expected-no-diagnostics } diff --git a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp index dd8e9c6b7fc11..1ea8b98cd8636 100644 --- a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp +++ b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp @@ -27,6 +27,80 @@ class MemInit { C m = s; }; +namespace std { +typedef decltype(sizeof(int)) size_t; + +// libc++'s implementation +template class initializer_list { + const _E *__begin_; + size_t __size_; + + initializer_list(const _E *__b, size_t __s) : __begin_(__b), __size_(__s) {} + +public: + typedef _E value_type; + typedef const _E &reference; + typedef const _E &const_reference; + typedef size_t size_type; + + typedef const _E *iterator; + typedef const _E *const_iterator; + + initializer_list() : __begin_(nullptr), __size_(0) {} + + size_t size() const { return __size_; } + const _E *begin() const { return __begin_; } + const _E *end() const { return __begin_ + __size_; } +}; +} // namespace std + +#if __cplusplus >= 201703L +namespace test_rebuild { +template class C { +public: + C(std::initializer_list); +}; + +template using Ptr = __remove_pointer(T) *; +template C(T) -> C, sizeof(T)>; + +class A { +public: + template T1 *some_func(T2 &&); +}; + +struct B : A { + // Test CXXDefaultInitExpr rebuild issue in + // https://github.com/llvm/llvm-project/pull/87933 + int *ar = some_func(C{some_func(0)}); + B() {} +}; + +int TestBody_got; +template class Vector { +public: + Vector(std::initializer_list); +}; +template Vector(Ts...) -> Vector; +class ProgramBuilder { +public: + template int *create(ARGS); +}; + +struct TypeTest : ProgramBuilder { + int *str_f16 = create(Vector{0}); + TypeTest() {} +}; +class TypeTest_Element_Test : TypeTest { + void TestBody(); +}; +void TypeTest_Element_Test::TestBody() { + int *expect = str_f16; + &TestBody_got != expect; // expected-warning {{inequality comparison result unused}} +} +} // namespace test_rebuild +#endif // __cplusplus >= 201703L + #if __cplusplus >= 202002L // This test ensures cleanup expressions are correctly produced // in the presence of default member initializers. diff --git a/clang/test/SemaCXX/cxx1y-sized-deallocation.cpp b/clang/test/SemaCXX/cxx1y-sized-deallocation.cpp index 3ec65a6a64d1c..462f1725bb1c2 100644 --- a/clang/test/SemaCXX/cxx1y-sized-deallocation.cpp +++ b/clang/test/SemaCXX/cxx1y-sized-deallocation.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++1y -verify %s -fsized-deallocation -fexceptions -fcxx-exceptions +// RUN: %clang_cc1 -std=c++1y -verify %s -fexceptions -fcxx-exceptions using size_t = decltype(sizeof(0)); void operator delete(void *, size_t) noexcept; // expected-note {{'operator delete' declared here}} diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 4c6ef5adae7d2..b71dfc6ccaf4f 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -284,7 +284,7 @@ class Foo {}; // Verify that template template type parameter TTP is referenced/used in the // template arguments of the RHS. template typename TTP> -using Bar = Foo>; // expected-note {{candidate template ignored: could not match 'Foo>' against 'int'}} +using Bar = Foo>; // expected-note {{candidate template ignored: could not match 'Foo>' against 'int'}} template class Container {}; diff --git a/clang/test/SemaCXX/cxx23-assume.cpp b/clang/test/SemaCXX/cxx23-assume.cpp index e67d72ae0a995..9138501d726dd 100644 --- a/clang/test/SemaCXX/cxx23-assume.cpp +++ b/clang/test/SemaCXX/cxx23-assume.cpp @@ -28,7 +28,7 @@ bool f2(); template constexpr void f3() { - [[assume(T{})]]; // expected-error {{not contextually convertible to 'bool'}} expected-warning {{has side effects that will be discarded}} ext-warning {{C++23 extension}} + [[assume(T{})]]; // expected-error {{not contextually convertible to 'bool'}} expected-warning {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}} } void g(int x) { @@ -38,13 +38,13 @@ void g(int x) { S{}.f(); S{}.g(); S{}.g(); - [[assume(f2())]]; // expected-warning {{side effects that will be discarded}} ext-warning {{C++23 extension}} + [[assume(f2())]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}} - [[assume((x = 3))]]; // expected-warning {{has side effects that will be discarded}} // ext-warning {{C++23 extension}} - [[assume(x++)]]; // expected-warning {{has side effects that will be discarded}} // ext-warning {{C++23 extension}} - [[assume(++x)]]; // expected-warning {{has side effects that will be discarded}} // ext-warning {{C++23 extension}} - [[assume([]{ return true; }())]]; // expected-warning {{has side effects that will be discarded}} // ext-warning {{C++23 extension}} - [[assume(B{})]]; // expected-warning {{has side effects that will be discarded}} // ext-warning {{C++23 extension}} + [[assume((x = 3))]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}} + [[assume(x++)]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}} + [[assume(++x)]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}} + [[assume([]{ return true; }())]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}} + [[assume(B{})]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} // ext-warning {{C++23 extension}} [[assume((1, 2))]]; // expected-warning {{has no effect}} // ext-warning {{C++23 extension}} f3(); // expected-note {{in instantiation of}} @@ -58,6 +58,11 @@ void g(int x) { [[assume(true)]] while (false) {} // expected-error {{only applies to empty statements}} [[assume(true)]] label:; // expected-error {{cannot be applied to a declaration}} [[assume(true)]] goto label; // expected-error {{only applies to empty statements}} + + // Also check variant spellings. + __attribute__((__assume__(true))); // Should not issue a warning because it doesn't use the [[]] spelling. + __attribute__((assume(true))) {}; // expected-error {{only applies to empty statements}} + [[clang::assume(true)]] {}; // expected-error {{only applies to empty statements}} } // Check that 'x' is ODR-used here. @@ -86,7 +91,7 @@ static_assert(S{}.g()); // expected-error {{not an integral constant e template constexpr bool f4() { - [[assume(!T{})]]; // expected-error {{invalid argument type 'D'}} // expected-warning 2 {{side effects}} ext-warning {{C++23 extension}} + [[assume(!T{})]]; // expected-error {{invalid argument type 'D'}} // expected-warning 2 {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}} return sizeof(T) == sizeof(int); } @@ -132,8 +137,8 @@ static_assert(f5() == 2); // expected-note {{while checking constraint satisf // Do not validate assumptions whose evaluation would have side-effects. constexpr int foo() { int a = 0; - [[assume(a++)]] [[assume(++a)]]; // expected-warning 2 {{has side effects that will be discarded}} ext-warning 2 {{C++23 extension}} - [[assume((a+=1))]]; // expected-warning {{has side effects that will be discarded}} ext-warning {{C++23 extension}} + [[assume(a++)]] [[assume(++a)]]; // expected-warning 2 {{assumption is ignored because it contains (potential) side-effects}} ext-warning 2 {{C++23 extension}} + [[assume((a+=1))]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} ext-warning {{C++23 extension}} return a; } @@ -143,3 +148,13 @@ template void f() { [[assume(val)]]; // expected-error {{expression contains unexpanded parameter pack}} } + +namespace gh71858 { +int +foo (int x, int y) +{ + __attribute__((assume(x == 42))); + __attribute__((assume(++y == 43))); // expected-warning {{assumption is ignored because it contains (potential) side-effects}} + return x + y; +} +} diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index 07937deb66738..b70c02201ac3c 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -446,3 +446,11 @@ int h(int x) { } #endif + + +namespace GH91308 { + constexpr void f(auto) { + static_assert(false); + } + using R1 = decltype(&f); +} diff --git a/clang/test/SemaCXX/eval-crashes.cpp b/clang/test/SemaCXX/eval-crashes.cpp index 017df977b26b7..a06f60f71e9c7 100644 --- a/clang/test/SemaCXX/eval-crashes.cpp +++ b/clang/test/SemaCXX/eval-crashes.cpp @@ -25,11 +25,9 @@ namespace pr33140_0b { } namespace pr33140_2 { - // FIXME: The declaration of 'b' below should lifetime-extend two int - // temporaries. - struct A { int &&r = 0; }; // expected-note 2{{initializing field 'r' with default member initializer}} + struct A { int &&r = 0; }; struct B { A x, y; }; - B b = {}; // expected-warning 2{{lifetime extension of temporary created by aggregate initialization using a default member initializer is not yet supported}} + B b = {}; } namespace pr33140_3 { diff --git a/clang/test/SemaCXX/overload-decl.cpp b/clang/test/SemaCXX/overload-decl.cpp index 1201396996e75..5d1df89a0da7b 100644 --- a/clang/test/SemaCXX/overload-decl.cpp +++ b/clang/test/SemaCXX/overload-decl.cpp @@ -36,3 +36,20 @@ class X { int main() {} // expected-note {{previous definition is here}} int main(int,char**) {} // expected-error {{conflicting types for 'main'}} + + +namespace GH93456 { + +struct X { + static void f(); // expected-note {{previous declaration is here}} + void f() const; + // expected-error@-1 {{static and non-static member functions with the same parameter types cannot be overloaded}} +}; + +struct Y { + void f() const; // expected-note {{previous declaration is here}} + static void f(); + // expected-error@-1 {{static and non-static member functions with the same parameter types cannot be overloaded}} +}; + +} diff --git a/clang/test/SemaCXX/overload-template.cpp b/clang/test/SemaCXX/overload-template.cpp index 0fe13c479cce2..3277a17e5e450 100644 --- a/clang/test/SemaCXX/overload-template.cpp +++ b/clang/test/SemaCXX/overload-template.cpp @@ -58,3 +58,13 @@ namespace overloadCheck{ } } #endif + +namespace GH93076 { +template int b(a..., int); // expected-note-re 3 {{candidate function template not viable: no known conversion from 'int ()' to 'int' for {{.*}} argument}} +int d() { + (void)b(0, 0, d); // expected-error {{no matching function for call to 'b'}} + (void)b(0, d, 0); // expected-error {{no matching function for call to 'b'}} + (void)b(d, 0, 0); // expected-error {{no matching function for call to 'b'}} + return 0; + } +} diff --git a/clang/test/SemaCXX/overloaded-operator.cpp b/clang/test/SemaCXX/overloaded-operator.cpp index cab21d67a002f..0701a96d5d0ce 100644 --- a/clang/test/SemaCXX/overloaded-operator.cpp +++ b/clang/test/SemaCXX/overloaded-operator.cpp @@ -691,4 +691,15 @@ template A<*T> operator *() { return {}; } // expected-error@-1 {{overloaded 'operator*' must have at least one parameter of class or enumeration type}} } +namespace GH92275 { + +template +struct constant{}; + +template +auto operator *(constant) +{ return constant<(*x)>{}; } + +} + #endif diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp index 479039f284799..5a42a11b82da5 100644 --- a/clang/test/SemaCXX/recovery-expr-type.cpp +++ b/clang/test/SemaCXX/recovery-expr-type.cpp @@ -1,3 +1,5 @@ +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index 63157cfacdd98..6b3610d703e71 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -912,3 +912,20 @@ auto g() { } } + +namespace GH92680 { + +struct IntConstuctible { + IntConstuctible(std::source_location = std::source_location::current()); +}; + +template +auto construct_at(IntConstuctible) -> decltype(IntConstuctible()) { + return {}; +} + +void test() { + construct_at({}); +} + +} diff --git a/clang/test/SemaCXX/unavailable_aligned_allocation.cpp b/clang/test/SemaCXX/unavailable_aligned_allocation.cpp index be593eafe11d6..45fdec606ad1b 100644 --- a/clang/test/SemaCXX/unavailable_aligned_allocation.cpp +++ b/clang/test/SemaCXX/unavailable_aligned_allocation.cpp @@ -75,7 +75,7 @@ void testOveraligned() { // expected-error-re@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-23 {{if you supply your own aligned allocation functions}} -// expected-error-re@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is {{only|not}} available on}} +// expected-error-re@-24 {{aligned deallocation function of type 'void (void *, std::size_t, std::align_val_t) noexcept' is {{only|not}} available on}} // expected-note@-25 {{if you supply your own aligned allocation functions}} // expected-error-re@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is {{only|not}} available on}} @@ -143,19 +143,19 @@ OveralignedS2::~OveralignedS2() {} // expected-no-diagnostics #else #if defined(IOS) -// expected-error@-6 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on iOS 11 or newer}}} +// expected-error@-6 {{aligned deallocation function of type 'void (void *, std::size_t, std::align_val_t) noexcept' is only available on iOS 11 or newer}}} // expected-note@-7 {{if you supply your own aligned allocation functions}} #elif defined(TVOS) -// expected-error@-9 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on tvOS 11 or newer}}} +// expected-error@-9 {{aligned deallocation function of type 'void (void *, std::size_t, std::align_val_t) noexcept' is only available on tvOS 11 or newer}}} // expected-note@-10 {{if you supply your own aligned allocation functions}} #elif defined(WATCHOS) -// expected-error@-12 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}} +// expected-error@-12 {{aligned deallocation function of type 'void (void *, std::size_t, std::align_val_t) noexcept' is only available on watchOS 4 or newer}}} // expected-note@-13 {{if you supply your own aligned allocation functions}} #elif defined(MACOS) -// expected-error@-15 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}} +// expected-error@-15 {{aligned deallocation function of type 'void (void *, std::size_t, std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}} // expected-note@-16 {{if you supply your own aligned allocation functions}} #elif defined(ZOS) -// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is not available on z/OS}}} +// expected-error@-18 {{aligned deallocation function of type 'void (void *, std::size_t, std::align_val_t) noexcept' is not available on z/OS}}} // expected-note@-19 {{if you supply your own aligned allocation functions}} #endif #endif @@ -209,6 +209,9 @@ void *operator new(std::size_t __sz, std::align_val_t) { void operator delete(void *p, std::align_val_t) { } +void operator delete(void *p, std::size_t __sz, std::align_val_t) { +} + void testOveraligned2() { auto p = new ((std::align_val_t)8) OveralignedS; delete p; diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 749d9e135d941..73cc946ca0ce1 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5838,12 +5838,12 @@ class Foo5 { class Foo6 { - Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu1'}} - Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu2'}} - Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu3'}} + Mutex mu1 ACQUIRED_AFTER(mu3); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu1'}} + Mutex mu2 ACQUIRED_AFTER(mu1); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu2'}} + Mutex mu3 ACQUIRED_AFTER(mu2); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu3'}} - Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_b'}} - Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{Cycle in acquired_before/after dependencies, starting with 'mu_a'}} + Mutex mu_b ACQUIRED_BEFORE(mu_b); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu_b'}} + Mutex mu_a ACQUIRED_AFTER(mu_a); // expected-warning {{cycle in acquired_before/after dependencies, starting with 'mu_a'}} void test0() { mu_a.Lock(); diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-misuse.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-misuse.cpp index 126257e0fc477..106661491800b 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-misuse.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-pragma-misuse.cpp @@ -18,8 +18,8 @@ void endUnopened(int *x) { } void wrongOption() { -#pragma clang unsafe_buffer_usage start // expected-error{{Expected 'begin' or 'end'}} -#pragma clang unsafe_buffer_usage close // expected-error{{Expected 'begin' or 'end'}} +#pragma clang unsafe_buffer_usage start // expected-error{{expected 'begin' or 'end'}} +#pragma clang unsafe_buffer_usage close // expected-error{{expected 'begin' or 'end'}} } void unclosed(int * p1) { diff --git a/clang/test/SemaObjC/unguarded-availability.m b/clang/test/SemaObjC/unguarded-availability.m index d0e23eabcb598..ecd91990174ae 100644 --- a/clang/test/SemaObjC/unguarded-availability.m +++ b/clang/test/SemaObjC/unguarded-availability.m @@ -177,16 +177,28 @@ void justAtAvailable(void) { #ifdef OBJCPP -int f(char) AVAILABLE_10_12; +int f(char) AVAILABLE_10_12; // #f_char_def int f(int); template int use_f() { - // FIXME: We should warn here! - return f(T()); + if (@available(macos 10.12, *)) { + return f(T()); // no warning expected + } else { + // expected-warning@#f_call {{'f' is only available on macOS 10.12 or newer}} + // expected-note@#f_char_inst {{in instantiation of function template specialization 'use_f' requested here}} + // expected-note@#f_char_def {{'f' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9}} + // expected-note@#f_call {{enclose 'f' in an @available check to silence this warning}} + return f(T()); // #f_call + } } int a = use_f(); -int b = use_f(); +int b = use_f(); // #f_char_inst + +int use_f2() AVAILABLE_10_12 { + int c = use_f(); + int d = use_f(); // no warning expected +} template int use_at_available() { if (@available(macos 10.12, *)) diff --git a/clang/test/SemaOpenACC/compute-construct-attach-clause.c b/clang/test/SemaOpenACC/compute-construct-attach-clause.c index de735308528ad..deca99f5bae47 100644 --- a/clang/test/SemaOpenACC/compute-construct-attach-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-attach-clause.c @@ -16,7 +16,7 @@ void uses() { #pragma acc parallel attach(LocalInt) while (1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel attach(&LocalInt) while (1); diff --git a/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp b/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp index 6d2efcf81eb6e..69f65f4083ae7 100644 --- a/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp +++ b/clang/test/SemaOpenACC/compute-construct-clause-ast.cpp @@ -40,6 +40,89 @@ void NormalFunc(int i, float f) { // CHECK-NEXT: WhileStmt // CHECK-NEXT: CXXBoolLiteralExpr // CHECK-NEXT: NullStmt + +#pragma acc parallel reduction(+: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: + + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(*: f) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: * + // CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc parallel reduction(max: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: max + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(min: f) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: min + // CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc parallel reduction(&: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: & + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(|: f) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: | + // CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + +#pragma acc parallel reduction(^: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: ^ + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(&&: f) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: && + // CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + +#pragma acc parallel reduction(||: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: || + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt } template @@ -154,6 +237,98 @@ void TemplFunc() { // CHECK-NEXT: CXXBoolLiteralExpr // CHECK-NEXT: NullStmt + T t; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} t 'T' + +#pragma acc parallel reduction(+: t) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: + + // CHECK-NEXT: DeclRefExpr{{.*}} 'T' lvalue Var{{.*}} 't' 'T' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(*: T::SomeFloat) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: * + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + typename T::IntTy i; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} i 'typename T::IntTy' + +#pragma acc parallel reduction(max: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: max + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename T::IntTy' lvalue Var{{.*}} 'i' 'typename T::IntTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(min: t) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: min + // CHECK-NEXT: DeclRefExpr{{.*}} 'T' lvalue Var{{.*}} 't' 'T' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc parallel reduction(&: T::SomeFloat) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: & + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(|: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: | + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename T::IntTy' lvalue Var{{.*}} 'i' 'typename T::IntTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc parallel reduction(^: t) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: ^ + // CHECK-NEXT: DeclRefExpr{{.*}} 'T' lvalue Var{{.*}} 't' 'T' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc serial reduction(&&: T::SomeFloat) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: && + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + +#pragma acc parallel reduction(||: i) + while(true); + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: || + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename T::IntTy' lvalue Var{{.*}} 'i' 'typename T::IntTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + // Match the instantiation: // CHECK: FunctionDecl{{.*}}TemplFunc{{.*}}implicit_instantiation // CHECK-NEXT: TemplateArgument type 'InstTy' @@ -262,6 +437,79 @@ void TemplFunc() { // CHECK-NEXT: CXXBoolLiteralExpr // CHECK-NEXT: NullStmt + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} t 'InstTy' + // CHECK-NEXT: CXXConstructExpr + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: + + // CHECK-NEXT: DeclRefExpr{{.*}} 'InstTy' lvalue Var{{.*}} 't' 'InstTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: * + // CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} i 'typename InstTy::IntTy':'int' + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: max + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename InstTy::IntTy':'int' lvalue Var{{.*}} 'i' 'typename InstTy::IntTy':'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: min + // CHECK-NEXT: DeclRefExpr{{.*}} 'InstTy' lvalue Var{{.*}} 't' 'InstTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: & + // CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: | + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename InstTy::IntTy':'int' lvalue Var{{.*}} 'i' 'typename InstTy::IntTy':'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: ^ + // CHECK-NEXT: DeclRefExpr{{.*}} 'InstTy' lvalue Var{{.*}} 't' 'InstTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}serial + // CHECK-NEXT: reduction clause Operator: && + // CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCComputeConstruct{{.*}}parallel + // CHECK-NEXT: reduction clause Operator: || + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename InstTy::IntTy':'int' lvalue Var{{.*}} 'i' 'typename InstTy::IntTy':'int' + // CHECK-NEXT: WhileStmt + // CHECK-NEXT: CXXBoolLiteralExpr + // CHECK-NEXT: NullStmt + } struct BoolConversion{ operator bool() const;}; diff --git a/clang/test/SemaOpenACC/compute-construct-copy-clause.c b/clang/test/SemaOpenACC/compute-construct-copy-clause.c index accbe43cea406..2b43480be8b4f 100644 --- a/clang/test/SemaOpenACC/compute-construct-copy-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-copy-clause.c @@ -36,11 +36,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel copy(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy(+IntParam) while(1); @@ -53,10 +53,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy((float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-copy-clause.cpp b/clang/test/SemaOpenACC/compute-construct-copy-clause.cpp index 16e78a43026a9..2797927e6e56b 100644 --- a/clang/test/SemaOpenACC/compute-construct-copy-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-copy-clause.cpp @@ -31,11 +31,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel copy(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy(+IntParam) while(1); @@ -48,27 +48,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel copy(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copy(t, I) while(true); @@ -93,7 +93,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel copy(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-copyin-clause.c b/clang/test/SemaOpenACC/compute-construct-copyin-clause.c index 6f200b357f52b..5ea4db9e5fae9 100644 --- a/clang/test/SemaOpenACC/compute-construct-copyin-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-copyin-clause.c @@ -38,11 +38,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel copyin(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(+IntParam) while(1); @@ -55,14 +55,14 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin((float)ArrayParam[2]) while(1); // expected-error@+2{{invalid tag 'invalid' on 'copyin' clause}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(invalid:(float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-copyin-clause.cpp b/clang/test/SemaOpenACC/compute-construct-copyin-clause.cpp index 79275e701161b..74ce74a1368d1 100644 --- a/clang/test/SemaOpenACC/compute-construct-copyin-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-copyin-clause.cpp @@ -31,11 +31,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel copyin(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(+IntParam) while(1); @@ -48,27 +48,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel copyin(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyin(t, I) while(true); @@ -93,7 +93,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel copyin(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-copyout-clause.c b/clang/test/SemaOpenACC/compute-construct-copyout-clause.c index 38a50f8373e8d..a035ab3242e3a 100644 --- a/clang/test/SemaOpenACC/compute-construct-copyout-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-copyout-clause.c @@ -38,11 +38,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel copyout(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(+IntParam) while(1); @@ -55,14 +55,14 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout((float)ArrayParam[2]) while(1); // expected-error@+2{{invalid tag 'invalid' on 'copyout' clause}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(invalid:(float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-copyout-clause.cpp b/clang/test/SemaOpenACC/compute-construct-copyout-clause.cpp index 3d05a5670092e..c01dc1a39963b 100644 --- a/clang/test/SemaOpenACC/compute-construct-copyout-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-copyout-clause.cpp @@ -31,11 +31,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel copyout(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(+IntParam) while(1); @@ -48,27 +48,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel copyout(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel copyout(t, I) while(true); @@ -93,7 +93,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel copyout(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-create-clause.c b/clang/test/SemaOpenACC/compute-construct-create-clause.c index 9c94e3a1a4073..5cfa9b0c5cc3c 100644 --- a/clang/test/SemaOpenACC/compute-construct-create-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-create-clause.c @@ -39,11 +39,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel create(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(+IntParam) while(1); @@ -56,14 +56,14 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create((float)ArrayParam[2]) while(1); // expected-error@+2{{invalid tag 'invalid' on 'create' clause}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(invalid:(float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-create-clause.cpp b/clang/test/SemaOpenACC/compute-construct-create-clause.cpp index d0323620b8f70..3ed1e1e9f700d 100644 --- a/clang/test/SemaOpenACC/compute-construct-create-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-create-clause.cpp @@ -31,11 +31,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel create(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(+IntParam) while(1); @@ -48,27 +48,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel create(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel create(t, I) while(true); @@ -93,7 +93,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel create(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c index 15c9cf396c80c..bf2a00a0f7360 100644 --- a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c @@ -182,7 +182,7 @@ void uses() { while(1); // expected-error@+2{{OpenACC clause 'reduction' may not follow a 'device_type' clause in a compute construct}} // expected-note@+1{{previous clause is here}} -#pragma acc kernels device_type(*) reduction(+:Var) +#pragma acc serial device_type(*) reduction(+:Var) while(1); // expected-error@+2{{OpenACC clause 'collapse' may not follow a 'device_type' clause in a compute construct}} // expected-note@+1{{previous clause is here}} diff --git a/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c b/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c index e5d328eb0b28b..ae8269b9779a4 100644 --- a/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-deviceptr-clause.c @@ -16,7 +16,7 @@ void uses() { #pragma acc parallel deviceptr(LocalInt) while (1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel deviceptr(&LocalInt) while (1); diff --git a/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c b/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c index 4e057bf32c2d6..eacda7bbbbba2 100644 --- a/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.c @@ -29,11 +29,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel firstprivate(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate(+IntParam) while(1); @@ -46,10 +46,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate((float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.cpp b/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.cpp index 2fbb80f7b2fbd..161e4012c08d5 100644 --- a/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-firstprivate-clause.cpp @@ -32,11 +32,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel firstprivate(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate(+IntParam) while(1); @@ -49,27 +49,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel firstprivate((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel private(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(t, I) while(true); @@ -94,7 +94,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel private(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-no_create-clause.c b/clang/test/SemaOpenACC/compute-construct-no_create-clause.c index 07a60b73c34f8..4ff06eaf132b0 100644 --- a/clang/test/SemaOpenACC/compute-construct-no_create-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-no_create-clause.c @@ -28,11 +28,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel no_create(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create(+IntParam) while(1); @@ -45,10 +45,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create((float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp b/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp index 3820d5e3999d5..fa84b1fbeda07 100644 --- a/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-no_create-clause.cpp @@ -31,11 +31,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel no_create(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create(+IntParam) while(1); @@ -48,27 +48,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel no_create(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel no_create(t, I) while(true); @@ -93,7 +93,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel no_create(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-present-clause.c b/clang/test/SemaOpenACC/compute-construct-present-clause.c index 99c4b1dcd19b4..1d50a6b1275b8 100644 --- a/clang/test/SemaOpenACC/compute-construct-present-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-present-clause.c @@ -28,11 +28,11 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo #pragma acc parallel present(LocalComposite.ScalarMember, LocalComposite.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present(+IntParam) while(1); @@ -45,10 +45,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present((float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-present-clause.cpp b/clang/test/SemaOpenACC/compute-construct-present-clause.cpp index 62e481dea3e24..db230d0b1d9da 100644 --- a/clang/test/SemaOpenACC/compute-construct-present-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-present-clause.cpp @@ -31,11 +31,11 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos #pragma acc parallel present(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present(1 + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present(+IntParam) while(1); @@ -48,27 +48,27 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present((float)ArrayParam[2]) while(1); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present(+t) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel present(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel present(t, I) while(true); @@ -93,7 +93,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel present(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-private-clause.c b/clang/test/SemaOpenACC/compute-construct-private-clause.c index d2615c384cdb1..3e6dbaafbc6fa 100644 --- a/clang/test/SemaOpenACC/compute-construct-private-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-private-clause.c @@ -89,13 +89,13 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo // Invalid cases, arbitrary expressions. struct Incomplete *I; - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(*I) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(GlobalInt + IntParam) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(+GlobalInt) while(1); @@ -128,10 +128,10 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo while(1); // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private((float*)ArrayParam[2:5]) while(1); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private((float)ArrayParam[2]) while(1); } diff --git a/clang/test/SemaOpenACC/compute-construct-private-clause.cpp b/clang/test/SemaOpenACC/compute-construct-private-clause.cpp index a776b16f0feb2..fb9e89a21accb 100644 --- a/clang/test/SemaOpenACC/compute-construct-private-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-private-clause.cpp @@ -64,34 +64,34 @@ void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete Compos // Invalid cases, arbitrary expressions. Incomplete *I; - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(*I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(GlobalInt + IntParam) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(+GlobalInt) while(true); } template void TemplUses(T t, T (&arrayT)[I], V TemplComp) { - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(+t) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(+I) while(true); // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#TEMPL_USES_INST{{in instantiation of}} #pragma acc parallel private(I) while(true); - // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} #pragma acc parallel private(t, I) while(true); @@ -120,7 +120,7 @@ void TemplUses(T t, T (&arrayT)[I], V TemplComp) { template void NTTP() { // NTTP's are only valid if it is a reference to something. - // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} + // expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} // expected-note@#NTTP_INST{{in instantiation of}} #pragma acc parallel private(I) while(true); diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-clause.c b/clang/test/SemaOpenACC/compute-construct-reduction-clause.c new file mode 100644 index 0000000000000..9c0debd345031 --- /dev/null +++ b/clang/test/SemaOpenACC/compute-construct-reduction-clause.c @@ -0,0 +1,107 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct CompositeOfScalars { + int I; + float F; + short J; + char C; + double D; + _Complex float CF; + _Complex double CD; +}; + +struct CompositeHasComposite { + int I; + float F; + short J; + char C; + double D; + _Complex float CF; + _Complex double CD; + struct CompositeOfScalars COS; // #COS_FIELD +}; + +void uses(unsigned Parm) { + float Var; + int IVar; + +#pragma acc parallel reduction(+:Parm) + while (1); +#pragma acc serial reduction(+:Parm) + while (1); + // expected-error@+1{{OpenACC 'reduction' clause is not valid on 'kernels' directive}} +#pragma acc kernels reduction(+:Parm) + while (1); + + // On a 'parallel', 'num_gangs' cannot have >1 args. num_gangs not valid on + // 'serial', but 'reduction' not valid on 'kernels', other combos cannot be + // tested. +#pragma acc parallel reduction(+:Parm) num_gangs(IVar) + while (1); +#pragma acc parallel num_gangs(IVar) reduction(+:IVar) + while (1); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel reduction(+:Parm) num_gangs(Parm, IVar) + while (1); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel num_gangs(Parm, IVar) reduction(+:Var) + while (1); + + struct CompositeOfScalars CoS; + struct CompositeOfScalars *CoSPtr; + struct CompositeHasComposite ChC; + struct CompositeHasComposite *ChCPtr; + + int I; + float F; + int Array[5]; + + // Vars in a reduction must be a scalar or a composite of scalars. +#pragma acc parallel reduction(&: CoS, I, F) + while (1); + // expected-error@+2{{OpenACC 'reduction' composite variable must not have non-scalar field}} + // expected-note@#COS_FIELD{{invalid field is here}} +#pragma acc parallel reduction(&: ChC) + while (1); + + // expected-error@+1{{OpenACC 'reduction' variable must be of scalar type, sub-array, or a composite of scalar types; type is 'int[5]'}} +#pragma acc parallel reduction(&: Array) + while (1); + +#pragma acc parallel reduction(&: CoS, Array[I], Array[0:I]) + while (1); + + struct CompositeHasComposite ChCArray[5]; + // expected-error@+1{{OpenACC 'reduction' variable must be of scalar type, sub-array, or a composite of scalar types; sub-array base type is 'struct CompositeHasComposite'}} +#pragma acc parallel reduction(&: CoS, Array[I], ChCArray[0:I]) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: CoS.I) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: CoSPtr->I) + + while (1); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: ChC.COS) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: ChCPtr->COS) + while (1); + +#pragma acc parallel reduction(&: I) reduction(&:I) + while (1); + + struct HasArray { int array[5]; } HA; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&:HA.array[1:2]) + while (1); +} diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp b/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp new file mode 100644 index 0000000000000..532dbb2387165 --- /dev/null +++ b/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp @@ -0,0 +1,175 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct CompositeOfScalars { + int I; + float F; + short J; + char C; + double D; + _Complex float CF; + _Complex double CD; +}; + +struct CompositeHasComposite { + int I; + float F; + short J; + char C; + double D; + _Complex float CF; + _Complex double CD; + struct CompositeOfScalars COS; // #COS_FIELD +}; + +void uses(unsigned Parm) { + float Var; + int IVar; + +#pragma acc parallel reduction(+:Parm) + while (1); +#pragma acc serial reduction(+:Parm) + while (1); + // expected-error@+1{{OpenACC 'reduction' clause is not valid on 'kernels' directive}} +#pragma acc kernels reduction(+:Parm) + while (1); + + // On a 'parallel', 'num_gangs' cannot have >1 args. num_gangs not valid on + // 'serial', but 'reduction' not valid on 'kernels', other combos cannot be + // tested. +#pragma acc parallel reduction(+:Parm) num_gangs(IVar) + while (1); +#pragma acc parallel num_gangs(IVar) reduction(+:Var) + while (1); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel reduction(+:Parm) num_gangs(Parm, IVar) + while (1); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel num_gangs(Parm, IVar) reduction(+:Var) + while (1); + +#pragma acc parallel reduction(+:Parm) reduction(+:Parm) + while (1); + + struct CompositeOfScalars CoS; + struct CompositeOfScalars *CoSPtr; + struct CompositeHasComposite ChC; + struct CompositeHasComposite *ChCPtr; + + int I; + float F; + int Array[5]; + + // Vars in a reduction must be a scalar or a composite of scalars. +#pragma acc parallel reduction(&: CoS, I, F) + while (1); + // expected-error@+2{{OpenACC 'reduction' composite variable must not have non-scalar field}} + // expected-note@#COS_FIELD{{invalid field is here}} +#pragma acc parallel reduction(&: ChC) + while (1); + // expected-error@+1{{OpenACC 'reduction' variable must be of scalar type, sub-array, or a composite of scalar types; type is 'int[5]'}} +#pragma acc parallel reduction(&: Array) + while (1); + +#pragma acc parallel reduction(&: CoS, Array[I], Array[0:I]) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: CoS.I) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: CoSPtr->I) + + while (1); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: ChC.COS) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: ChCPtr->COS) + while (1); +} + +template +void TemplUses(T Parm, U CoS, V ChC) { + T Var; + U *CoSPtr; + V *ChCPtr; + +#pragma acc parallel reduction(+:Parm) + while (1); +#pragma acc serial reduction(+:Parm) + while (1); + // expected-error@+1{{OpenACC 'reduction' clause is not valid on 'kernels' directive}} +#pragma acc kernels reduction(+:Parm) + while (1); + + // On a 'parallel', 'num_gangs' cannot have >1 args. num_gangs not valid on + // 'serial', but 'reduction' not valid on 'kernels', other combos cannot be + // tested. +#pragma acc parallel reduction(+:Parm) num_gangs(Var) + while (1); +#pragma acc parallel num_gangs(Var) reduction(+:Var) + while (1); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel reduction(+:Parm) num_gangs(Parm, Var) + while (1); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel num_gangs(Parm, Var) reduction(+:Var) + while (1); + +#pragma acc parallel reduction(+:Parm) reduction(+:Parm) + while (1); + + int NonDep; + int NonDepArray[5]; + T Array[5]; + + // Vars in a reduction must be a scalar or a composite of scalars. +#pragma acc parallel reduction(&: CoS, Var, Parm) + while (1); + // expected-error@+2{{OpenACC 'reduction' composite variable must not have non-scalar field}} + // expected-note@#COS_FIELD{{invalid field is here}} +#pragma acc parallel reduction(&: ChC) + while (1); + // expected-error@+1{{OpenACC 'reduction' variable must be of scalar type, sub-array, or a composite of scalar types; type is 'int[5]'}} +#pragma acc parallel reduction(&: Array) + while (1); + // expected-error@+1{{OpenACC 'reduction' variable must be of scalar type, sub-array, or a composite of scalar types; type is 'int[5]'}} +#pragma acc parallel reduction(&: NonDepArray) + while (1); + +#pragma acc parallel reduction(&: CoS, Array[Var], Array[0:Var]) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: CoS.I) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: CoSPtr->I) + + while (1); + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: ChC.COS) + while (1); + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, or composite variable member}} +#pragma acc parallel reduction(&: ChCPtr->COS) + while (1); +} + +void inst() { + CompositeOfScalars CoS; + CompositeHasComposite ChC; + // expected-note@+1{{in instantiation of function template specialization}} + TemplUses(5, CoS, ChC); +} diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error.cl index b044763edcf00..7a550f026bc1b 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-error.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error.cl @@ -155,8 +155,8 @@ void test_ds_fmaxf(local float *out, float src, int a) { void test_fence() { __builtin_amdgcn_fence(__ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} __builtin_amdgcn_fence(__ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} - __builtin_amdgcn_fence(4); // expected-error {{too few arguments to function call, expected 2}} - __builtin_amdgcn_fence(4, 4, 4); // expected-error {{too many arguments to function call, expected 2}} + __builtin_amdgcn_fence(4); // expected-error {{too few arguments to function call, expected at least 2, have 1}} + __builtin_amdgcn_fence(4, 4, 4); // expected-error {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}} __builtin_amdgcn_fence(3.14, ""); // expected-warning {{implicit conversion from 'double' to 'unsigned int' changes value from 3.14 to 3}} __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, 5); // expected-error {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}} const char ptr[] = "workgroup"; diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl b/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl new file mode 100644 index 0000000000000..487cc53e8ad8a --- /dev/null +++ b/clang/test/SemaOpenCL/builtins-amdgcn-gfx940-err.cl @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -cl-std=CL2.0 -O0 -triple amdgcn-unknown-unknown -target-cpu gfx940 -S -verify -o - %s +// REQUIRES: amdgpu-registered-target + +typedef unsigned int u32; + +void test_global_load_lds_unsupported_size(global u32* src, local u32 *dst, u32 size) { + __builtin_amdgcn_global_load_lds(src, dst, size, /*offset=*/0, /*aux=*/0); // expected-error{{expression is not an integer constant expression}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/5, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/0, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/3, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/12, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/16, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} + __builtin_amdgcn_global_load_lds(src, dst, /*size=*/-1, /*offset=*/0, /*aux=*/0); // expected-error{{invalid size value}} expected-note {{size must be 1, 2, or 4}} +} diff --git a/clang/test/SemaOpenCL/vector_swizzle_length.cl b/clang/test/SemaOpenCL/vector_swizzle_length.cl index f36ae201205e0..b06cc126c3eca 100644 --- a/clang/test/SemaOpenCL/vector_swizzle_length.cl +++ b/clang/test/SemaOpenCL/vector_swizzle_length.cl @@ -5,6 +5,6 @@ typedef float float8 __attribute__((ext_vector_type(8))); void foo(void) { float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0); - f2.s01234; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} - f2.xyzxy; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} + f2.s01234; // expected-error {{vector component access has invalid length 5; supported lengths are: 1,2,3,4,8,16}} + f2.xyzxy; // expected-error {{vector component access has invalid length 5; supported lengths are: 1,2,3,4,8,16}} } diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index a91ab5ec7bcc5..91c35d98fbf57 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -100,11 +100,11 @@ using CT = C; // CHECK: | `-NonTypeTemplateParmDecl {{.*}} 'X' depth 1 index 1 // CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 2 U // CHECK: |-NonTypeTemplateParmDecl {{.*}} 'type-parameter-0-2' depth 0 index 3 V -// CHECK: | `-TemplateArgument expr +// CHECK: | `-TemplateArgument {{.*}} expr // CHECK: | `-IntegerLiteral {{.*}} 'int' 0 -// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (A, Y<>, type-parameter-0-2) -> C' +// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (A, Y, type-parameter-0-2) -> C' // CHECK: | |-ParmVarDecl {{.*}} 'A' -// CHECK: | |-ParmVarDecl {{.*}} 'Y<>' +// CHECK: | |-ParmVarDecl {{.*}} 'Y' // CHECK: | `-ParmVarDecl {{.*}} 'type-parameter-0-2' // CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (int, Y, int) -> C' // CHECK: |-TemplateArgument type 'int' @@ -114,12 +114,12 @@ using CT = C; // CHECK: |-ParmVarDecl {{.*}} 'int' // CHECK: |-ParmVarDecl {{.*}} 'Y' // CHECK: `-ParmVarDecl {{.*}} 'int' -// CHECK: FunctionProtoType {{.*}} 'auto (A, Y<>, type-parameter-0-2) -> C' dependent trailing_return cdecl +// CHECK: FunctionProtoType {{.*}} 'auto (A, Y, type-parameter-0-2) -> C' dependent trailing_return cdecl // CHECK: |-InjectedClassNameType {{.*}} 'C' dependent // CHECK: |-TemplateTypeParmType {{.*}} 'A' dependent depth 0 index 0 // CHECK: | `-TemplateTypeParm {{.*}} 'A' -// CHECK: |-ElaboratedType {{.*}} 'Y<>' sugar dependent -// CHECK: | `-TemplateSpecializationType {{.*}} 'Y<>' dependent Y +// CHECK: |-ElaboratedType {{.*}} 'Y' sugar dependent +// CHECK: | `-TemplateSpecializationType {{.*}} 'Y' dependent Y // CHECK: | `-TemplateArgument template // CHECK: `-TemplateTypeParmType {{.*}} 'type-parameter-0-2' dependent depth 0 index 2 @@ -139,7 +139,7 @@ using DT = D; // CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 ... T // CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 1 U1 // CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 2 U2 -// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (B *) -> D' +// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (B *) -> D' // CHECK: `-ParmVarDecl {{.*}} 'B *' // CHECK: FunctionProtoType {{.*}} 'auto (B *) -> D' dependent trailing_return // CHECK: |-InjectedClassNameType {{.*}} 'D' dependent @@ -222,7 +222,7 @@ F s(0); // CHECK-LABEL: Dumping : // CHECK: FunctionTemplateDecl // CHECK: |-NonTypeTemplateParmDecl {{.*}} 'char' depth 0 index 0 -// CHECK: `-TemplateArgument expr +// CHECK: `-TemplateArgument {{.*}} expr // CHECK: | |-inherited from NonTypeTemplateParm {{.*}} '' 'char' // CHECK: | `-CharacterLiteral {{.*}} 'char' 120 // CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 1 U @@ -299,3 +299,34 @@ using AFoo = Foo>; // CHECK-NEXT: `-ParmVarDecl {{.*}} 'G' AFoo aa(G{}); + +namespace TTP { + template struct A {}; + + template struct B { + template